Returning specific part of a file path?

Discussion in 'Plugin Development' started by DiamGamingWTF, Jul 9, 2015.

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

    DiamGamingWTF

    Right, what I am trying to do is grab the beginning of a path within a file called "Towns" by checking if a player is within the list inside of that path. Essentially, trying to get the name of a higher part of the path ... Allow me to explain in easier words;
    This is my file:
    Code:
    Towns:
      TownNameOne:
        CitizenList:
          - UUID1
          - UUID2
      TownNameTwo:
        CitizenList:
          -UUID3
    Now, I know how to get the CitizenList by specifying the name of the town, but I want to be able to scan through the file and get what town a UUID is in without specifying the town. The method of getting the citizens in a specified town I use is currently:
    Code:
    public List getTownCitizens(String TownName) {
            List<UUID> CitizenList = new ArrayList<UUID>();
            CitizenList.addAll((Collection<? extends UUID>) Town.getList("Towns." + TownName + ".CitizenList"));
           
            return CitizenList;
        }
    What i'm trying at the moment to get a citizen from a town without specifying the town name is:
    Code:
    for (Object s : Towns.getList("Towns")) {
            String TownName = (String) s;
            if (getTownCitizens(TownName).contains(p.getUniqueId())) { return TownName;} 
    }
    All this does is return a null error in the console at the line "Object s : Towns.getList". I am relatively new to reading through files like this but I'm hoping some of you guys can help me with my current problem. Thank you.
     
  2. The reason you're getting 'null' is because getList() returns a List, but "Towns" in your File is a Map (stored as a ConfigurationSection). I don't think there's an efficient way to do this at all since you're looking for a value, not a key, but I'll leave my way:

    Code:
    // If the configuration doesn't contain "Towns", just return null.
    if (!Towns.contains("Towns")) return null;
    
    // Loop through every entry set in the Map (the Towns configuration section).
    for (Map.Entry<String, Object> townEntry : Towns.getConfigurationSection("Towns").getValues(false).entrySet()) {
        // Check if the value is a ConfigurationSection.
        if (townEntry.getValue() instanceof ConfigurationSection) {
            ConfigurationSection townSection = (ConfigurationSection) townEntry.getValue();
            // Get the List of UUIDs (as a String)
            List<String> townUUIDs = townSection.getStringList("CitizenList");
            // Check if the List of UUIDs contains the player's UUID (as a String).
            if (townUUIDs.contains(p.getUniqueId().toString())) return townEntry.getKey();
        }
    }
    
    // Return null if they're not in any towns.
    return null;
    
    By the way, I'd recommend following Java programming conventions and renaming 'Towns' to 'towns' or even better, 'townsConfig'. Don't start your method and variable names with capital letters unless it's a static variable, use camelCasing.
     
    Last edited: Jul 9, 2015
    DiamGamingWTF likes this.
  3. @KingFaris11
    That method is usable, but if the config contains another list on another type of path it would break. @DiamGamingWTF
    Personally, I would do something like this:
    Code:
    public String getTown(Player p) { //Some random method
      String uuid = p.getUniqueId().toString();
      for(String town : Towns.getConfigurationSection("Towns").getKeys(false)) { //This returns a set of paths directly after the specified section
        if(Towns.getStringList("Towns." + town + ".CitizenList").contains(uuid)) { //Check if the list contains the uuid
          return town; //If it contains the uuid, return the town name
        }
      }
    }
    return null; //The player is not in a town :(
     
    DiamGamingWTF likes this.
  4. That also would work, and is probably more efficient. However, that point about 'if the config contains another list on another type of path' doesn't make sense to me, since "CitizenList" will always be returning a List<String>.
     
    DiamGamingWTF likes this.
  5. Offline

    DiamGamingWTF

    @KingFaris11 and @megamichiel
    Thanks so much for your assistance.
    Also, thanks for the suggestion on camelCasing, I haven't actually heard of that method of naming variables/methods before.
     
  6. @KingFaris11
    I mean if there's another list on a different path (not in the towns section) it could break, e.g.:
    Code:
    Towns:
      TownName:
        CitizenList:
        - Bleh
        - SomeGuy
      AnotherTown:
        CitizenList:
        - Meow
        - Woof
    SomeRandomList: #This could break it, since it's not a town citizen list
    - ListItem1
    - ListItem2
     
  7. Offline

    DiamGamingWTF

    @megamichiel By the way, do you know how to add to the list in a file? I know how to set but I'm not sure how to add a UUID to a town CitizenList...
     
  8. @DiamGamingWTF
    1. Get the list from the config (getStringList)
    2. Add stuff to the list
    3. Set it back in the config
     
    DiamGamingWTF likes this.
  9. Offline

    DiamGamingWTF

Thread Status:
Not open for further replies.

Share This Page