Solved Reading from Config.yml as an array

Discussion in 'Spigot Plugin Development' started by MXR156, Aug 14, 2019.

  1. Hi All,

    I am trying to streamline a little of my code, however I'm not too sure it is possible (Although I am a bit of a Java noob so I could be wrong). I am building a plugin that applies a permission to mining certain ores/blocks so you have to unlock things to progress. The plugin itself works perfectly, and I know what you're going to say, "If it aint broke dont fix it". But it's a mess haha.

    I have a config file as such
    Code (YAML):

    LockCoalOre
    : true
    LockIronOre
    : true
    LockRedstoneOre
    : true
    LockLapisOre
    : true
    LockGoldOre
    : true
    LockDiamondOre
    : true
    LockEmeraldOre
    : true
    LockQuartzOre
    : true

    Ores
    :
        COAL_ORE
    :
            name
    : Coal
            locked
    : true
            perm
    : mine.coal
        IRON_ORE
    :
            name
    : Iron
            locked
    : true
            perm
    : mine.iron
        REDSTONE_ORE
    :
            name
    : Redstone
            locked
    : true
            perm
    : mine.redstone
        LAPIS_ORE
    :
            name
    : Lapis
            locked
    : true
            perm
    : mine.lapis
    And basically what I am doing is tying to check the YAML file for the "Ores" array instead of the individual disabled above it, and if the ore is in there and you dont have the permission cancel the event and tell them they dont have permission with the below.

    Code (Java):

           Boolean LockCoalOre = getConfig().getBoolean("LockCoalOre");
           Boolean LockIronOre = getConfig().getBoolean("LockIronOre");
           Boolean LockRedstoneOre = getConfig().getBoolean("LockRedstoneOre");
           Boolean LockLapisOre = getConfig().getBoolean("LockLapisOre");
           Boolean LockGoldOre = getConfig().getBoolean("LockGoldOre");
           Boolean LockDiamondOre = getConfig().getBoolean("LockDiamondOre");
           Boolean LockEmeraldOre = getConfig().getBoolean("LockEmeraldOre");
           Boolean LockQuartzOre = getConfig().getBoolean("LockQuartzOre");
           
           Player player = event.getPlayer();
           
    //       ArrayList<Boolean> OreArray = new ArrayList<>();
    //       List<Boolean> OreArray = getConfig().getBooleanList("Ores");
    //       player.sendMessage("Array: " + ChatColor.DARK_RED + OreArray);

            //Check for Coal Ore Permissions
            if (event.getBlock().getBlockData().getMaterial() == Material.COAL_ORE) {
                if(LockCoalOre == true) {
                    if(!player.hasPermission("orelocks.mine.coal")) {
                        BlockBreakError(player,Material.COAL_BLOCK.name());
                        event.setCancelled(true);
                        return;
                    } else {}
                } else {}
            }
            //Check for Iron Ore Permissions
            if (event.getBlock().getBlockData().getMaterial() == Material.IRON_ORE) {
                if(LockIronOre == true) {
                    if(!player.hasPermission("orelocks.mine.iron")) {
                        BlockBreakError(player,Material.COAL_BLOCK.name());
                        event.setCancelled(true);
                        return;
                    } else {}
                } else {}
            }
            //Check for Redstone Ore Permissions
            if (event.getBlock().getBlockData().getMaterial() == Material.REDSTONE_ORE) {
                if(LockRedstoneOre == true) {
                    if(!player.hasPermission("orelocks.mine.redstone")) {
                        BlockBreakError(player,Material.COAL_BLOCK.name());
                        event.setCancelled(true);
                        return;
                    } else {}
                } else {}
            }
    As you can see, I have included the Old method so that the plugin still works, but I want to make the code smaller with something like

    If Ore is in "Ores" array > Does Player have permission node Y/N > Lock or allow to mine and send message.

    Hope this makes a little sense..

    Thanks in advance
     
  2. Did you tried List<String> list=getConfig().getConfigurationSection("Ores").getKeys(false);?
     
    • Like Like x 1
  3. First of all, please follow the Java naming conventions.

    The way I would approach this is as follows.
    I would create a config:
    Code (YAML):
    ores:
      COAL_ORE
    : true
      IRON_ORE
    : true
      # the rest of them, or you can have the user imput them
    You can then simply get the ConfigurationSection associated with "ores" (ConfigurationSection#getConfigurationSection) and iterate over ConfigurationSection#etKeys. You could then check if the key matches a material with Material#matchMaterial, if it does, you'll add an entry to a Map<Material, Boolean> (You can check to make sure it's within a subset if you don't want users to include other random types in the config).
    I suggest caching the map and only redoing the above when needed (i.e if you've got a command that reloads the config).

    You can then check if the Map contains Block#getMaterial and if it does, you get the value from the map. If that returns true, it's "blocked", otherwise it's allowed.
     
    • Like Like x 1
  4. This seems to have pulled out the list of config sections that I want which is great! I can work with this a little better.

    I dont quite understand what you mean with the Naming Conventions, As far as I am aware everything I have written albeit jumbled is correct in the manner of speaking. So if I need to change the way I put things across, I apologise.. But as I stated I am a little new to Java and do not do it professionally.

    Other things being said does make a lot of sense, but that's the bit I am confused about, Either way I have had another read of this and see what I can pull together.

    Thanks,
     
  5. You can create StringList in Config. As next you can get these lists by getStringList(). =)
     
  6. Benz56

    Moderator Supporter

    Variables should be lowerCamelCase.
    https://www.oracle.com/technetwork/java/codeconventions-135099.html

    The empty else {} statements are redundant. You can remove those.
     
    • Like Like x 1
  7. The above methods work great, and I've strung together this code.

    Code (Java):
            Player player = event.getPlayer();
         
            Set<String> oreArray=getConfig().getConfigurationSection("ores").getKeys(false);
         
            Material block = event.getBlock().getType();
            String minedBlock = block.toString();
         
            player.sendMessage("Array: " + ChatColor.DARK_RED + oreArray);
            player.sendMessage("Mined Block: " + ChatColor.DARK_RED + minedBlock);
         
            if(oreArray.contains(minedBlock)){
                player.sendMessage("Stop that!");
                event.setCancelled(true);
                return;
            }
    Which is 10x smaller than the original code which is part of the challenge complete.

    Could anyone explain how I could get the configuration section of the YAML file to then confirm if it is locked, and the permission node for it?

    I guess it would be something like this? Just not 100% sure how I would get a sub section of a YAML config file.

    Code (Java):
    String permission = getConfig().getConfigurationSection("ores").getString(minedBlock + "permission");
    The YAML file is set out like this

    Code (YAML):
    ores:
        COAL_ORE
    :
            locked
    : true
            permission
    : mine.coal
        IRON_ORE
    :
            locked
    : true
            permission
    : mine.iron
        REDSTONE_ORE
    :
            locked
    : true
            permission
    : mine.redstone
    I'm quite possibly miles off with the above :confused:
     
  8. Benz56

    Moderator Supporter

    It’s actually quite simple.
    Code (Java):
    boolean locked = getConfig().getBoolean(“ores.” + minedBlock + “.locked);
    String permission = getConfig().getString(“ores.” + minedBlock + “.permission);
     
    • Like Like x 1
  9. Code (Java):
            MemorySection materials = (MemorySection) config.get("ores");
            if (materials != null) {
                for (String material : materials.getKeys(false)) {
                    boolean locked = materials.getBoolean(material + ".locked");
                    String permission = materials.getString(material + ".permission");
                }
            }
     
    • Like Like x 1
  10. Absolutely perfect! Final code to work on is below and it works just as I would like it to. Now to put the if statements in and I'll be done. Thanks for the assistance all :D

    Code (Java):

           Player player = event.getPlayer();
         
           Set<String> oreArray=getConfig().getConfigurationSection("ores").getKeys(false);

           Material block = event.getBlock().getType();
           String minedBlock = block.toString();
         
           player.sendMessage("Array: " + ChatColor.DARK_RED + oreArray);
           player.sendMessage("Mined Block: " + ChatColor.DARK_RED + minedBlock);
         
            if(oreArray.contains(minedBlock)){
               boolean locked = getConfig().getBoolean("ores." + minedBlock + ".locked");
               String permission = getConfig().getString("ores." + minedBlock + ".permission");
               player.sendMessage("Locked? " + ChatColor.DARK_RED + locked);
               player.sendMessage("Permission: " + ChatColor.DARK_RED + permission);
               player.sendMessage("Stop that!");
               event.setCancelled(true);
               return;
            }
     
    I just echod oud the config files to see what they were reading as for testing.