Read YAML data

Discussion in 'Plugin Development' started by indyetoile, Jun 15, 2014.

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

    indyetoile

    Hello!

    I am currently developing a minigame plugin, and I don't seem to understand how I can get a value of a string in custom YAML files.

    I have a Yaml class:
    Code:java
    1.  
    2. package me.indy226.game;
    3. import java.io.File;
    4. import java.io.FileNotFoundException;
    5. import java.io.IOException;
    6.  
    7.  
    8. import org.bukkit.Bukkit;
    9. import org.bukkit.configuration.InvalidConfigurationException;
    10. import org.bukkit.configuration.file.FileConfiguration;
    11. import org.bukkit.configuration.file.YamlConfiguration;
    12. import org.bukkit.configuration.file.YamlConfigurationOptions;
    13. import org.bukkit.entity.Player;
    14. import org.bukkit.event.EventHandler;
    15. import org.bukkit.event.EventPriority;
    16. import org.bukkit.event.Listener;
    17. import org.bukkit.event.player.PlayerJoinEvent;
    18.  
    19. public class Yaml implements Listener {
    20. @EventHandler(priority = EventPriority.HIGH)
    21. public void onJoin(PlayerJoinEvent event){
    22. Player player = event.getPlayer();
    23. String playern = player.getName();
    24. // This creates a file inside your plugins data folder inside the folder "UserData"
    25. File userdata = new File(Bukkit.getServer().getPluginManager().getPlugin("BoneHunter").getDataFolder(), File.separator + "UserData");
    26. File f = new File(userdata, File.separator + playern + ".yml");
    27. FileConfiguration playerData = YamlConfiguration.loadConfiguration(f);
    28.  
    29. if(!f.exists()){
    30. try {
    31. f.createNewFile();
    32. } catch (IOException e) {
    33.  
    34. e.printStackTrace();
    35. }
    36.  
    37. try {
    38. try {
    39. try {
    40. playerData.load(f);
    41. // Here you can set what you want to be in the player file by default
    42. playerData.set("kit", "Juggernaut");
    43. playerData.save(f);
    44. } catch (FileNotFoundException e) {
    45. // TODO Auto-generated catch block
    46. e.printStackTrace();
    47. }
    48. } catch (IOException e) {
    49. // TODO Auto-generated catch block
    50. e.printStackTrace();
    51. }
    52. } catch (InvalidConfigurationException e) {
    53. // TODO Auto-generated catch block
    54. e.printStackTrace();
    55. }
    56. }
    57. }
    58. public void Kit(Player p, String s){
    59.  
    60.  
    61. }
    62.  
    63.  
    64. }


    It creates a YAML file for every player when they join, with Juggernaut set as their default kit. However, I now want to read from the configuration in my main class.

    I already tried copy-pasting the part of where it loads the YAML file to my main class, and use
    Code:java
    1. if(playerData.getString("kit").equalsIgnoreCase("Juggernaut")
    , but that didn't seem to work.

    Does anyone know a solution to this?

    Thank you!
     
  2. In your Yaml class you could cache all the FileConfigurations and have a plugin instance object (Main is the main class, yours could be different).
    Code:
    private Map<String, FileConfiguration> playerConfigs = new HashMap<String, FileConfiguration>();
    private Main pluginInstance = null;
     
    public Yaml(Main plugin) {
        this.pluginInstance = plugin;
    }
     
    @EventHandler(priority = EventPriority.HIGH)
    public void onJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        String playerName = player.getName();
        FileConfiguration playerConfig = this.getPlayerConfig(playerName);
        if (!playerConfig.contains("kit")) playerConfig.set("kit", "Juggernaut");
        this.savePlayerFile(playerName, playerConfig);
    }
     
    public FileConfiguration getPlayerConfig(String playerName) {
        if (this.playerConfigs.containsKey(playerName)) {
            return this.playerConfigs.get(playerName);
        } else {
            FileConfiguration playerConfig = YamlConfiguration.loadConfiguration(this.getPlayerFile(playerName));
            this.playerConfigs.put(playerName, playerConfig);
            return playerConfig;
        }
    }
     
    public File getPlayerFile(String playerName) {
        return new File(this.pluginInstance.getDataFolder(), "UserData" + File.seperator + playerName + ".yml");
    }
     
    public void savePlayerFile(String playerName) {
        try {
            if (this.playerConfigs.containsKey(playerName)) this.playerConfigs.get(playerName).save(this.getPlayerFile(playerName));
        } catch (Exception ex) {
        }
    }
     
    public void savePlayerFile(String playerName, FileConfiguration playerConfig) {
        try {
            playerConfig.save(this.getPlayerFile(playerName));
        } catch (Exception ex) {
        }
    }
    
    Then in your main class:
    Code:
    private Yaml yamlListener = null;
     
    public void onEnable() {
        this.yamlListener = new Yaml(this);
        this.yamlListener.getPlayerConfig("KingFaris10"); // Etc.
    }
    
    Your example in this context:
    Code:
    if (this.yamlListener.getPlayerConfig("PLAYER_USERNAME").getString("kit", "Juggernaut").equalsIgnoreCase("Juggernaut")) {
        // Do something
    }
    
     
    AronTheGamer and indyetoile like this.
  3. Offline

    indyetoile

    KingFaris11

    Thank you for your help! I just realized it wasn't the main class wherein I wanted to read data, but in another class.
    However,
    Code:java
    1. String player = p.getName();
    2. if (this.yamlListener.getPlayerConfig(player).getString("kit", "Juggernaut").equalsIgnoreCase("Juggernaut")){
    3. // code
    4. }
    5.  

    gives me a NullPointerException (also if I replace player with "PLAYER_NAME").

    Besides, do I have to add
    Code:java
    1. this.yamlListener.getPlayerConfig("KingFaris10"); // Etc.
    for each player apart? Wouldn't there be a way to automate this?

    Also, I don't understand why you wrote "kit", "Juggernaut", because if it has another value it wouldn't work right?

    Thank you.
     
  4. I probably know why but I'm afk for an hour, I will reply soon.
     
    indyetoile likes this.
  5. Offline

    indyetoile

  6. Probably because either yamlListener is null OR your plugin instance when loading yamlListener is null.
    Make sure to call: new Yaml(this);

    Also, no you don't need to do that, I was just giving an example of how to get the player config.

    Lastly, I did "("kit", "Juggernaut")" because if the config doesn't exist or "kit" does not exist in the config or is something like an integer or a double, using getString() may throw an error (not sure), so instead of throwing the error or returning null, return "Juggernaut" by default.

    You could also load all configs in onEnable() if you want:
    http://pastie.org/private/i8tjj4ehvsbpxc5tlavw
    http://pastie.org/private/ejy1qx88ssd789z6s1myw

    If you don't want to load all configs in onEnable(), you might want to listen to PlayerQuitEvent and do:
    this.deleteConfig(event.getPlayer().getName());
     
  7. Offline

    malandrix_bunny

    I know it is not directly relevant, but you are storing a player's name, not their UUID. I would recommend storing the UUID instead just to avoid namechanges ruining your plugin.
     
  8. Offline

    indyetoile

    Okay, somehow this is really confusing me.

    This is my Arena class, wherein I want to request the player YAML data:
    Code:java
    1. package me.indy226.game;
    2.  
    3. import java.io.File;
    4. import java.io.FileNotFoundException;
    5. import java.io.IOException;
    6. import java.util.ArrayList;
    7.  
    8. import me.indy226.game.ArenaManager.Team;
    9. import me.indy226.game.Yaml;
    10.  
    11. import org.bukkit.Bukkit;
    12. import org.bukkit.ChatColor;
    13. import org.bukkit.DyeColor;
    14. import org.bukkit.GameMode;
    15. import org.bukkit.Location;
    16. import org.bukkit.Material;
    17. import org.bukkit.configuration.ConfigurationSection;
    18. import org.bukkit.configuration.InvalidConfigurationException;
    19. import org.bukkit.configuration.file.FileConfiguration;
    20. import org.bukkit.configuration.file.YamlConfiguration;
    21. import org.bukkit.entity.Player;
    22. import org.bukkit.event.EventHandler;
    23. import org.bukkit.event.EventPriority;
    24. import org.bukkit.event.player.PlayerJoinEvent;
    25. import org.bukkit.inventory.ItemStack;
    26. import org.bukkit.inventory.meta.ItemMeta;
    27. import org.bukkit.material.Wool;
    28. import org.bukkit.scoreboard.Objective;
    29. import org.bukkit.scoreboard.Score;
    30. import org.bukkit.scoreboard.Scoreboard;
    31. import org.bukkit.scoreboard.ScoreboardManager;
    32.  
    33. public class Arena {
    34.  
    35. private int id;
    36. private boolean started = false;
    37. private boolean cd = false;
    38. private Location redspawn, bluespawn;
    39. private ArrayList<PlayerData> players = new ArrayList<PlayerData>();
    40.  
    41. private Scoreboard sb;
    42. private Objective o;
    43. private Score red, blue;
    44.  
    45. public Arena(int id) {
    46. this.id = id;
    47.  
    48. ConfigurationSection conf = SettingsManager.getInstance().get(id + "");
    49.  
    50. this.redspawn = getLocation(conf.getConfigurationSection("redspawn"));
    51. this.bluespawn = getLocation(conf.getConfigurationSection("bluespawn"));
    52.  
    53. sb = Bukkit.getScoreboardManager().getNewScoreboard();
    54. o = sb.registerNewObjective("BoneHunter", "dummy");
    55. red = o.getScore(Bukkit.getServer().getOfflinePlayer(ChatColor.RED + "Red"));
    56. blue = o.getScore(Bukkit.getServer().getOfflinePlayer(ChatColor.BLUE + "Blue"));
    57. }
    58.  
    59. public void onEnable() {
    60. this.yamlListener = new Yaml(this);
    61. }
    62. private Yaml yamlListener = null;
    63.  
    64. private Location getLocation(ConfigurationSection path) {
    65. return new Location(
    66. Bukkit.getServer().getWorld(path.getString("world")),
    67. path.getDouble("x"),
    68. path.getDouble("y"),
    69. path.getDouble("z")
    70. );
    71. }
    72.  
    73. public int getID() {
    74. return id;
    75. }
    76.  
    77. public boolean isStarted() {
    78. return started;
    79. }
    80.  
    81. public void setStarted(boolean started) {
    82. this.started = started;
    83. }
    84.  
    85. public Location getSpawn(Team team) {
    86. switch(team) {
    87. case RED: return redspawn;
    88. case BLUE: return bluespawn;
    89. default: return null;
    90. }
    91. }
    92.  
    93. public Team getTeam(Player p) {
    94. return getData(p).getTeam();
    95. }
    96.  
    97. public void addPlayer(Player p) {
    98. players.add(new PlayerData(p.getName(), getTeamWithLessPlayers(), p.getInventory().getContents(), p.getInventory().getArmorContents(), p.getLocation()));
    99.  
    100. String player = p.getName().toString();
    101. if (this.yamlListener.getPlayerConfig(player).getString("kit", "Juggernaut").equalsIgnoreCase("Juggernaut")){
    102. p.getInventory().clear();
    103. p.getInventory().addItem(new ItemStack(Material.DIAMOND_SWORD, 1));
    104. }
    105.  
    106. p.teleport(getSpawn(getData(p).getTeam()));
    107.  
    108. p.setScoreboard(sb);
    109.  
    110. p.setGameMode(GameMode.SURVIVAL);
    111. p.setFlying(false);
    112.  
    113. MessageManager.getInstance().info(p, "You have joined arena " + getID() + " and are on the " + ChatColor.valueOf(getData(p).getTeam().toString()) + getData(p).getTeam().toString().toLowerCase() + ChatColor.GRAY + " team!");
    114.  
    115. if (players.size() >= 2 && !cd) start();
    116. }
    117.  
    118. public void removePlayer(Player p, boolean lost) {
    119. PlayerData pd = getData(p);
    120.  
    121. p.getInventory().clear();
    122. for (ItemStack i : pd.getContents()) if (i != null) p.getInventory().addItem(i);
    123. p.getInventory().setArmorContents(pd.getArmorContents());
    124.  
    125. p.teleport(pd.getLocation());
    126.  
    127. p.setScoreboard(Bukkit.getServer().getScoreboardManager().getNewScoreboard());
    128.  
    129. players.remove(pd);
    130.  
    131. if (lost) {
    132. MessageManager.getInstance().info(p, "You lost the game.");
    133. msg(p.getName() + " lost the game.");
    134. }
    135. }
    136.  
    137. public void start() {
    138. cd = true;
    139. msg("Game starting in 30 seconds!");
    140. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(SettingsManager.getInstance().getPlugin(), new Runnable() {
    141. public void run() {
    142. Arena.this.started = true;
    143. Arena.this.cd = false;
    144. msg("Good luck!");
    145. }
    146. }, 30 * 20);
    147. }
    148.  
    149. public void stop(Player winner) {
    150. msg(winner != null ? winner.getName() + " won the game!" : "The game was ended.");
    151. for (PlayerData pd : players) {
    152. Player p = Bukkit.getServer().getPlayer(pd.getPlayerName());
    153. removePlayer(p, true);
    154. }
    155. }
    156.  
    157. public void addDeath(Player p) {
    158. Team t = getTeam(p);
    159. if (t == Team.RED) blue.setScore(blue.getScore() + 1);
    160. else red.setScore(red.getScore() + 1);
    161. }
    162.  
    163. private void msg(String msg) {
    164. for (PlayerData pd : players) {
    165. Player p = Bukkit.getServer().getPlayer(pd.getPlayerName());
    166. MessageManager.getInstance().info(p, msg);
    167. }
    168. }
    169.  
    170. private Team getTeamWithLessPlayers() {
    171. int red = 0, blue = 0;
    172. for (PlayerData pd : players) {
    173. if (pd.getTeam() == Team.RED) red++;
    174. else blue++;
    175. }
    176. if (red > blue) return Team.BLUE;
    177. else return Team.RED;
    178. }
    179.  
    180. public boolean containsPlayer(Player p) {
    181. return getData(p) != null;
    182. }
    183.  
    184. private PlayerData getData(Player p) {
    185. for (PlayerData pd : players) {
    186. if (pd.getPlayerName().equalsIgnoreCase(p.getName())) return pd;
    187. }
    188. return null;
    189. }
    190.  
    191. }


    And here's my Yaml file:
    Code:java
    1.  
    2. package me.indy226.game;
    3. import java.io.File;
    4. import java.io.FileNotFoundException;
    5. import java.io.IOException;
    6.  
    7.  
    8. import java.util.ArrayList;
    9. import java.util.HashMap;
    10. import java.util.List;
    11. import java.util.Map;
    12.  
    13. import org.bukkit.Bukkit;
    14. import org.bukkit.configuration.InvalidConfigurationException;
    15. import org.bukkit.configuration.file.FileConfiguration;
    16. import org.bukkit.configuration.file.YamlConfiguration;
    17. import org.bukkit.configuration.file.YamlConfigurationOptions;
    18. import org.bukkit.entity.Player;
    19. import org.bukkit.event.EventHandler;
    20. import org.bukkit.event.EventPriority;
    21. import org.bukkit.event.Listener;
    22. import org.bukkit.event.player.PlayerJoinEvent;
    23.  
    24. public class Yaml implements Listener {
    25. private Map<String, FileConfiguration> playerConfigs = new HashMap<String, FileConfiguration>();
    26. private Arena pluginInstance = null;
    27.  
    28. public Yaml(Arena arena) {
    29. this.pluginInstance = arena;
    30. }
    31.  
    32. @EventHandler(priority = EventPriority.HIGH)
    33. public void onJoin(PlayerJoinEvent event) {
    34. Player player = event.getPlayer();
    35. String playerName = player.getName();
    36. FileConfiguration playerConfig = this.getPlayerConfig(playerName);
    37. if (!playerConfig.contains("kit")) playerConfig.set("kit", "Juggernaut");
    38. this.savePlayerFile(playerName, playerConfig);
    39. }
    40.  
    41. public FileConfiguration getPlayerConfig(String playerName) {
    42. if (this.playerConfigs.containsKey(playerName)) {
    43. return this.playerConfigs.get(playerName);
    44. } else {
    45. FileConfiguration playerConfig = YamlConfiguration.loadConfiguration(this.getPlayerFile(playerName));
    46. this.playerConfigs.put(playerName, playerConfig);
    47. return playerConfig;
    48. }
    49. }
    50.  
    51. public File getPlayerFile(String playerName) {
    52. File dataFolder = Bukkit.getPluginManager().getPlugin("BoneHunter").getDataFolder();
    53. return new File(dataFolder, "UserData" + File.separator + playerName + ".yml");
    54. }
    55.  
    56. public void savePlayerFile(String playerName) {
    57. try {
    58. if (this.playerConfigs.containsKey(playerName)) this.playerConfigs.get(playerName).save(this.getPlayerFile(playerName));
    59. } catch (Exception ex) {
    60. }
    61. }
    62.  
    63. public void savePlayerFile(String playerName, FileConfiguration playerConfig) {
    64. try {
    65. playerConfig.save(this.getPlayerFile(playerName));
    66. } catch (Exception ex) {
    67. }
    68. }
    69.  
    70.  
    71. }


    As you can see I added OnEnable in my Arena class. I also tried adding it in the Main class, but I didn't succeed.

    Yet this returns null, on line 101 of Arena.java. Could you or anyone else please check my code and tell me what I've done wrong?

    I'd really appreciate it.
    Thank you.
     
  9. Line 59-61:
    That won't work. Yaml is meant to take the main class plugin instance, not the Arena class as it requires access to getDataFolder().

    This means also changing:
    Code:
    File dataFolder = Bukkit.getPluginManager().getPlugin("BoneHunter").getDataFolder();
    To:
    Code:
    File dataFolder = this.pluginInstance.getDataFolder();
    Although you could just completely remove the need for pluginInstance and the constructor and just use Bukkit.getPluginManager() instead.

    Also, you're probably not calling the onEnable() method from your main class. You should really always have your main class instance everywhere. Example:
    https://github.com/KingFaris10/SkinChanger/blob/master/src/com/faris/skinchanger/Main.java#L17
    Line 17, 39, 229.

    Try this:
    Code:
    if (this.yamlListener != null) {
        FileConfiguration playerConfig = this.yamlListener.getPlayerConfig(player);
        if (playerConfig != null) {
            String playerKit = playerConfig.getString("kit", "Juggernaut");
            if (playerKit.equalsIgnoreCase("Juggernaut")) {
                p.getInventory().clear();
                p.getInventory().addItem(new ItemStack(Material.DIAMOND_SWORD, 1));
            }
        }
    }
    
    Edit: Please tag me as I can't see your comments as a notification unless you do so.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
Thread Status:
Not open for further replies.

Share This Page