Solved Ordering a list of Int's from a config

Discussion in 'Plugin Development' started by ProSl3nderMan, Aug 20, 2015.

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

    ProSl3nderMan

    I really need help with this one, I've done so much research on ordering lists of ints and have not found one simple code that works. This is what I got so far:
    LeaderBoards command:
    Code:
             if (args[0].equalsIgnoreCase("top")) {
               
                for(String top: AccessControl.plugin.getConfig().getConfigurationSection("players.").getKeys(false)){
                    String name = AccessControl.plugin.getConfig().getString("players." + top + ".IGN");
                    String wins = AccessControl.plugin.getConfig().getString("players." + top + ".GamesWon");
                }
            }
    Config:
    Code:
    players:
      dad48cab-4c99-419d-9330-821ee9ba83db:
        IGN: Nightmare_4_You
        game: '0'
        cop: 'no'
        GamesWon: 1
      3d40296c-c3d0-4acf-a3f2-4d924d186388:
        game: '0'
        cop: 'no'
        IGN: ProSl3nderMan
        GamesWon: 2
    I need help on getting the top 10 from that config and sorting it in order from greatest to least.
     
  2. Offline

    CraftCreeper6

    @ProSl3nderMan
    Put them in a List
    Use Collection.sort(list); then loop through ten of the values.
     
  3. Offline

    ProSl3nderMan

    This is what I got:
    Code:
                for(String top: AccessControl.plugin.getConfig().getConfigurationSection("players.").getKeys(false)){
                    String name = AccessControl.plugin.getConfig().getString("players." + top + ".IGN");
                    String wins = AccessControl.plugin.getConfig().getString("players." + top + ".GamesWon");
                    List<String> list = AccessControl.plugin.getConfig().getStringList("players." + top + ".GamesWon");
                    List<String> list2 = AccessControl.plugin.getConfig().getStringList("players." + top + ".IGN");
                    Collection.sort(list);
                }
    Am I doing this right?
     
  4. players.name.GamesWon and .IGN isn't a String list.
    You would have the list ABOVE the for-loop and inside you add the values of the current player to the for-loop.
    Also, when sorting a List<String>, it automaticly sorts it alphanumeric (or something like that ^^).
    You need to sort it with your own comparator:
    Code:
    Collections.sort(list, new Comparator<String>() {
    
    public int compare(String s1, String s2) {
    //If it only contains is an int:
    return new Integer(s1).compareTo(s2);
    //If not you need to replace/substring until you only have the int left
    }
    });
     
  5. Offline

    ProSl3nderMan

    I get an error on sort and compareTo:
    Code:
                for(String s : AccessControl.plugin.getConfig().getStringList("players.")) {
                      wins.put(s, Integer.valueOf(AccessControl.plugin.getConfig().getInt("players." + s + ".wins")));
                    }
                Collections.sort(wins, new Comparator<String>() {
                    public int compare(String s1, String s2) {
                        //If it only contains is an int:
                        return new Integer(s1).compareTo(s2);
                    }
                });
    Error sort:
    Error compareTo:
    Do I get these errors because GamesWon isn't a String list? If so, how do I turn all the ints I have into a String list?
     
    Last edited: Aug 20, 2015
  6. Offline

    mythbusterma

  7. Offline

    ProSl3nderMan

    The hasmap is suppose to be storing my list.
     
  8. Offline

    mythbusterma

    @ProSl3nderMan

    So you want to order the List or the Map?

    You should really think about not nesting Collections.
     
  9. Offline

    ProSl3nderMan

    I want to order the list and I thought I would need a hashmap to get the list out of the for-loop.
     
  10. Offline

    mythbusterma

  11. Offline

    ProSl3nderMan

    Alright, lets start back down from ground zero without the hashmap then. This is what I have:
    Code:
                for(String s : AccessControl.plugin.getConfig().getStringList("players.")) {
                         List<String> wins = AccessControl.plugin.getConfig().getStringList("players." + s + ".GamesWon");
                }
                Collections.sort(wins, new Comparator<String>() {
                    public int compare(String s1, String s2) {
                        //If it only contains is an int:
                        return new Integer(s1).compareTo(s2);
                    }
                });
    I understand there's a way to let the List<String> wins work outside the for-loop, but I have no clue on how to do so.
     
  12. Here is an example how to "sort" a HashMap<String, Integer>:
    Code:
    HashMap<String, Integer> hm = new HashMap<String, Integer>();
    //fill it
    
    List<String> sorted = new ArrayList<String>(hm.keySet());
    Collections.sort(sorted, new Comparator<String>() {
    public int compare(String s1, String s2) {
    return Integer.valueOf(hm.get(s2)).compareTo(hm.get(s1));
    }
    });
    Basically you need to sort the keys of the HashMap and then access the values of it with the key.
    If you want to get the highest, use:
    Code:
    hm.get(sorted.get(0));
    If you want to get the 2nd highest, use:
    Code:
    hm.get(sorted.get(1));
    etc.. But before you do this you need to make sure that the size of the HashMap is not smaller than 10 or make some for-loops that only go to max. 10 when printing it out
     
  13. Offline

    ProSl3nderMan

    @FisheyLP
    Thank you, this seems to be what I needed. I'll try it.

    @FisheyLP
    I get an error with this code:
    Code:
                List<String> sorted = new ArrayList<String>(hm.keySet());
                Collections.sort(sorted, new Comparator<String>() {
                    public int compare(String s1, String s2) {
                        return Integer.valueOf(hm.get(s2)).compareTo(hm.get(s1));
                    }
                });
                for(String s : AccessControl.plugin.getConfig().getStringList("players.")) {
                    hm.put(s, Integer.valueOf(AccessControl.plugin.getConfig().getInt("players." + s + ".GamesWon")));
                    }
                for (int i = 0; i < hm.size(); i++) {
                    if ((i < 11) ) {
                        int r = i + 1;
                        p.sendMessage(hm);
                    }
                }
    How do I send the player hm if it's an int?

    EDIT by Timtower: merged posts
     
    Last edited by a moderator: Aug 21, 2015
  14. You can't just send a HashMap.. You need to send a String.
    Loop through (no nested loop, normal with int i) the sorted list and then you can send the message containing the key (player name/current iteration in for-loop) and the value (hm.get(key))
     
  15. Offline

    ProSl3nderMan

    Alright, I think I got it down now. But I'm not getting any message when I do the command. Here's my code:
    Command code:
    Code:
          if (args[0].equalsIgnoreCase("top")) {
                for(String s : AccessControl.plugin.getConfig().getStringList("players.")) {
                    hm.put(s, Integer.valueOf(AccessControl.plugin.getConfig().getInt("players." + s + ".GamesWon")));
                }
                List<String> sorted = new ArrayList<String>(hm.keySet());
                Collections.sort(sorted, new Comparator<String>() {
                    public int compare(String s1, String s2) {
                        return Integer.valueOf(hm.get(s2)).compareTo(hm.get(s1));
                    }
                });
                for(Entry<String, Integer> i : hm.entrySet()) {
                    orderedScores.put((String)i.getKey(), (Integer)i.getValue());
                    players.add((String)i.getKey());
                }
              
                for (int i = 0; i < players.size() ; i++) {
                    if (i < 11 && (orderedScores.containsKey(players.get(i)))) {
                        int r = i + 1;
                        p.sendMessage(r + (String)players.get(i) + ": " + orderedScores.get(players.get(i)));
                    }
                }
    Config:
    Code:
    players:
      dad48cab-4c99-419d-9330-821ee9ba83db:
        IGN: Nightmare_4_You
        game: '0'
        cop: 'no'
        GamesWon: 1
      3d40296c-c3d0-4acf-a3f2-4d924d186388:
        IGN: ProSl3nderMan
        game: '1'
        cop: 'no'
        GamesWon: 2
    
     
  16. It isn't a StringList. It is a ConfigurationSection:
    Code:
    for (String player : config.getConfigurationSection("players").getKeys(false)) {
    And for sending you can just use:
    Code:
    [SIZE=16px]for (int i = 0; i < hm.size(); i++) {[/SIZE]
    if (i > 10) break;
    // send message: (i + 1) + ". " + sorted.get(i) + ": " + hm.get(sorted.get(i)):
    }
     
    Last edited: Aug 21, 2015
  17. Offline

    ProSl3nderMan

    @FisheyLP
    Dude, I love you! Haha, just came home from a church event and scraped up my foot pretty bad at the event. I came home to a code that works, a code that I've been trying to get work for a week xP Thanks a bunch dude.

    UPDATE: Actually, I need help for one tiny thing. The command displays the player's uuid, not the ign. It's how I store the uuid's and player name, so I switched them around. Can someone help me figure out how to loop through a list of player names looking at the UUID to find a match with the player's, that just joined, UUID?
     
    Last edited: Aug 21, 2015
  18. Maybe Bukkit.getOfflinePlayer(uuid).getName()

    Where uuid is UUID.fromString(str)
     
  19. Offline

    ProSl3nderMan

    @FisheyLP
    I don't understand how that will work. I need it to replace the previous IGN of the UUID the updated IGN. This is how my config looks:
    Code:
    players:
      Nightmare_4_You:
        UUID: dad48cab-4c99-419d-9330-821ee9ba83db
        game: '0'
        cop: 'no'
        GamesWon: 1
      ProSl3nderMan:
        UUID: 3d40296c-c3d0-4acf-a3f2-4d924d186388
        game: '0'
        cop: 'no'
        GamesWon: 2
    If I was to replace UUID with the IGN, it would print out the UUID instead of the IGN when I do the command to display top players. Is there a way to fix this?
     
    Last edited: Aug 24, 2015
  20. The config path contains the player name and the uuid... Show your code
     
  21. Offline

    ProSl3nderMan

    Ik it does, I need it to update the IGN with UUID under the IGN. Can't show code for my on join listener class, on the go.

    This is what I have:
    Code:
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
           
           
            Player p = event.getPlayer();
           
            int x = AccessControl.plugin.getConfig().getInt("lobby.x");
            int y = AccessControl.plugin.getConfig().getInt("lobby.y");
            int z = AccessControl.plugin.getConfig().getInt("lobby.z");
            p.teleport(new Location(Bukkit.getWorld(AccessControl.plugin.getConfig().getString("lobby.world")), x, y, z));
            for(String i : AccessControl.plugin.getConfig().getConfigurationSection("players.").getKeys(false)) {
                if (i == Bukkit.getOfflinePlayer(p.getUniqueId()).getName()) break; {
                    AccessControl.plugin.getConfig().set("players." +  Bukkit.getOfflinePlayer(p.getUniqueId()).getName() , p.getName());
                }
            }
       }
    When ever it finds the old player's IGN and is suppose to replace the old IGN with the new IGN, it just makes a total new one player. How do I make it edit the old name?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 11, 2016
  22. I don't know if it matters, but there should be no . after "players
    use .equals instead

    And how to edit/copy-paste a path/configuration section:
    Code:
    config.set("newPath", config.getConfigurationSection("oldPath"));
    config.set("oldPath", null);
    saveConfig();
     
  23. Offline

    ProSl3nderMan

    This is what I have now, it doesn't work:
    Code:
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
           
           
            Player p = event.getPlayer();
           
            int x = AccessControl.plugin.getConfig().getInt("lobby.x");
            int y = AccessControl.plugin.getConfig().getInt("lobby.y");
            int z = AccessControl.plugin.getConfig().getInt("lobby.z");
            p.teleport(new Location(Bukkit.getWorld(AccessControl.plugin.getConfig().getString("lobby.world")), x, y, z));
            String uuid = p.getPlayer().getUniqueId().toString();
            if(AccessControl.plugin.getConfig().contains("players." + Bukkit.getOfflinePlayer(p.getUniqueId()).getName())) {
                AccessControl.plugin.getConfig().set("players." + p.getName() , AccessControl.plugin.getConfig().getConfigurationSection("players." + Bukkit.getOfflinePlayer(p.getUniqueId()).getName()));
                AccessControl.plugin.getConfig().set("players." + Bukkit.getOfflinePlayer(p.getUniqueId()).getName() , null);
                AccessControl.plugin.saveConfig();
                AccessControl.plugin.reloadConfig();
            } else if(!AccessControl.plugin.getConfig().contains("players." + p.getName())) {
                AccessControl.plugin.getConfig().set("players." +  p.getName() , p.getName());
                AccessControl.plugin.getConfig().set("players." + p.getName() + ".UUID" , uuid);
                AccessControl.plugin.getConfig().set("players." + p.getName() + ".game" , "0");
                AccessControl.plugin.getConfig().set("players." + p.getName() + ".cop" , "no");
                AccessControl.plugin.getConfig().set("players." + p.getName() + ".GamesWon", 0);
            }
            AccessControl.plugin.saveConfig();
            AccessControl.plugin.reloadConfig();
           
        }
    It doesn't detect the old person's name.

    Someone please help me?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 11, 2016
  24. Offline

    Zombie_Striker

    @ProSl3nderMan
    What do you mean by "doesn't work". Please be more specific.

    btw, with the amount of times you are getting the config, you should create a field for the config instead of going through all those classes over and over again.
     
  25. Offline

    ProSl3nderMan

    It doesn't seem to be finding the old IGN of the person who just joined. And I'll see to that simpler way tomorrow.
     
  26. Offline

    Zombie_Striker

    @ProSl3nderMan
    1. Fix your code by creating a field which will store the config instance, thus making your code alot cleaner and much more efficient.
    2. Unless you are saving the players old name by saving their UUID (e.g. config.getString("oldname."+uuid)), it looks like the code you currently have will only get their current username.
    3. Post that updated code
     
  27. Offline

    ProSl3nderMan

    This is what I have:
    Code:
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
          
          
            Player p = event.getPlayer();
          
            int x = AccessControl.plugin.getConfig().getInt("lobby.x");
            int y = AccessControl.plugin.getConfig().getInt("lobby.y");
            int z = AccessControl.plugin.getConfig().getInt("lobby.z");
            p.teleport(new Location(Bukkit.getWorld(AccessControl.plugin.getConfig().getString("lobby.world")), x, y, z));
            for(String i : AccessControl.plugin.getConfig().getConfigurationSection("players.").getKeys(false)) {
                if (i.equals(Bukkit.getOfflinePlayer(p.getUniqueId()).getName())) break; {
                    AccessControl.plugin.getConfig().set("players." +  Bukkit.getOfflinePlayer(p.getUniqueId()).getName() , p.getName());
                }
            }
       }
    Can't do much rn, got to go to bed.
     
  28. Offline

    Zombie_Striker

    Let me add the field then and add some comments:
    Code:
        @EventHandler
        public void onJoin(PlayerJoinEvent event) {
             
            Player p = event.getPlayer();
            ConfiguationFile config =AccessControl.plugin.getConfig();
        
            int x = config.getInt("lobby.x");
            int y = config.getInt("lobby.y");
            int z = config.getInt("lobby.z");
            p.teleport(new Location(Bukkit.getWorld( config.getString("lobby.world")), x, y, z));// events fire BEFORE anything gets registered, which is why you can cancel events. You are trying to teleport a player that has not even connected yet, since onJoin fires BEFORE there is a player instance.
            for(String i : config.getConfigurationSection("players.").getKeys(false)) {
                if (i.equals(Bukkit.getOfflinePlayer(p.getUniqueId()).getName())) 
                    break; 
                {//first, do you mean equals ignore case(allows for capital letter changing). Secondly, Why the break? Finally, What are you doing with that bracket? This should cause an error if you're using an IDE
                    config.set("players." +  Bukkit.getOfflinePlayer(p.getUniqueId()).getName() , p.getName());
                }
            }
       }
     
  29. Offline

    au2001

    @ProSl3nderMan It's a FileConfiguration, not a ConfigurationFile.
    And it is ConfigurationSection.getValues(false).keySet(), not ConfigurationSection.getKeys(false) I think.
     
  30. Offline

    ProSl3nderMan

    1: Yes, that's what I meant.
    2: I don't know why, I just added it.
    3: If I take out that bracket, my code lights up like the Forth of July hehe.
    I really need help with this. In the config under players, I have lists of names with their UUID beneath it.. If I was to switch these two around and do the /cr top command (sorts the top 10) it will print out the UUID, not the name. So if someone could just help me make it print out the name instead of the UUID, then everything is fixed.
     
Thread Status:
Not open for further replies.

Share This Page