Statistics Leaderboard

Discussion in 'Plugin Development' started by The Fancy Whale, Feb 17, 2014.

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

    The Fancy Whale

    I currently have a plugin which I am trying to implement top statistics.
    Here is what the stats file currently looks like:
    Code:
    TheFancyWhale:
      stats: 201
    Dinnerbone:
      stats: 435
    Is there a way to check who has the highest stats
     
  2. Offline

    ItsLeandro

    Yes you can get the player with the highest stats.
    First let the plugin get all the players stats, and than let him get the highest number (Stats in this case).
     
  3. Offline

    The Fancy Whale

    ItsLeandro I cant think of any ways to do this. Would I have to rearrange the way my config is formatted?
     
  4. Offline

    ItsLeandro

    No you don't need to rearrange your config :)
     
  5. Offline

    The Fancy Whale

    ItsLeandro How would I get all the players stats without a players section?
     
  6. Offline

    DonkeyTeeth2013

    The Fancy Whale Use a for loop and a hashmap like so:
    Code:java
    1. //not tested!
    2.  
    3. HashMap<String, Integer> stats = new HashMap<String, Integer>();
    4. for(Player player : playersToGetStatsFrom){
    5. stats.put(player.getName(), getConfig().getInt(player.getName() + ".stats"));
    6. }


    If you want it to just loop through everything in the config instead of for certain players:
    Code:java
    1. HashMap<String, Integer> stats = new HashMap<String, Integer>();
    2. for(String player : getConfig().getKeys()){
    3. stats.put(player, getConfig().getInt(player + ".stats"));
    4. }
     
  7. Offline

    The Fancy Whale

    Not working for me... I am might be using it wrong though.
     
  8. Offline

    DonkeyTeeth2013

    The Fancy Whale Ah, I see my error. Where it says .getKeys(), change it to .getKeys(false) (Keep in mind I didn't test this beforehand)

    Basically what it's doing is just looping through all the keys in the config, then adding them to a hashmap based on the key.
     
  9. Offline

    The Fancy Whale

  10. Offline

    DonkeyTeeth2013

    The Fancy Whale By "not working" do you mean you're getting errors in Eclipse or it doesn't do anything when you test it? (If you're getting errors please post them)
     
  11. Offline

    The Fancy Whale

  12. Offline

    DonkeyTeeth2013

  13. Offline

    The Fancy Whale

    On the first line:
    Code:
    Multiple markers at this line
        - Watchpoint:Main [access and modification] -
        poop
        - Syntax error on token ";", { expected after this
        token
    Second Line:
    Code:
    Multiple markers at this line
        - Syntax error on token ")", ; expected
        - Syntax error on token(s), misplaced construct(s)
        - Return type for the method is missing
        - The method getKeys(boolean) is undefined for the type
        Main
        - Syntax error on token ".", { expected
    And fourth line:
    Code:
    Syntax error, insert "}" to complete
    MethodBody
     
  14. Offline

    DonkeyTeeth2013

    The Fancy Whale Hmm, all I could say is that it's probably a problem with the surrounding code. It worked fine for me as you see in this picture:
    [​IMG]
    Check the surrounding code for a missing ; or extra } or some other error.
     
  15. Offline

    The Fancy Whale

    DonkeyTeeth2013 Ph I forgot to put public void *MAJOR DERP*
    But I am still confused how I would use this to check who has the highest.
     
  16. Offline

    DonkeyTeeth2013

    The Fancy Whale This just adds everything to a hashmap so you can use it. To get the highest value, loop through the values and get the highest value, and then get the key that the value belongs to like this:
    Code:java
    1. String max = null;
    2. int maxValueInMap=(Collections.max(stats.values())); // This will return max value in the Hashmap
    3. for (Entry<String, Integer> entry : stats.entrySet()) { // Itrate through hashmap
    4. if (entry.getValue()==maxValueInMap) {
    5. max = entry.getKey();
    6. }
    7. }
    8. Player player = Bukkit.getPlayer(max); //Do stuff with the player

    So your entire method looks like this:
    Code:java
    1. public Player getHighestPlayer(){
    2. HashMap<String, Integer> stats = new HashMap<String, Integer>();
    3. for(String player : getConfig().getKeys(false)){
    4. stats.put(player, getConfig().getInt(player + ".stats"));
    5. }
    6.  
    7. String max = null;
    8. int maxValueInMap=(Collections.max(stats.values()));
    9. for (Entry<String, Integer> entry : stats.entrySet()) {
    10. if (entry.getValue()==maxValueInMap) {
    11. max = entry.getKey();
    12. }
    13. }
    14. Player player = Bukkit.getPlayer(max);
    15. return player;
    16. }
     
    The Fancy Whale likes this.
  17. Offline

    The Fancy Whale

    "The method getKeys(boolean) in the type MemorySection is not applicable for the arguments ()"
    error on line 3 on the .getKeys
    "Type mismatch: cannot convert from element type Map.Entry<String,Integer> to Entry"
    Error on stats.entryset

    BTW Thanks sooo much for your help ive been working on this for about a month.
     
  18. Offline

    DonkeyTeeth2013

    The Fancy Whale For the first error, looks like I derped again and forgot to put .getKeys(false) (I edited that in just now)
    For the second error, make sure the hashmap type is <String, Integer> & the entry type is also <String, Integer>
     
    The Fancy Whale likes this.
  19. Offline

    The Fancy Whale

    When I added the .getKeys(false) it fixed the other issue as well. Thanks!

    DonkeyTeeth2013 Thanks so much again and sorry one last question. Is it possible to get top 5 rather than just number 1?

    DonkeyTeeth2013 Also, how would I get their name in a command. I need to take that variable and make it usable somewhere else

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

    DonkeyTeeth2013

    The Fancy Whale No problem :) If you want the top 5, just remove the key from the hashmap and look again for the next highest, and keep repeating that until you have a total of 5 players.

    For your second question, do you mean get the player's name when they type a command?
     
    The Fancy Whale likes this.
  21. Offline

    The Fancy Whale

    DonkeyTeeth2013 Thanks I'll see the code I can write to get 2-5 and get back to you.
    Then for the second question I mean so I have a command to get the top players. However I am not sure how to access the integer. Does that make sense sort of?
     
  22. Offline

    DonkeyTeeth2013

    The Fancy Whale Simply move the hashmap outside of the method so that it's used by the entire class (make sure to clear the hashmap when you're done with it) and when you need a value just do stats.get(player.getName()), and that will return the integer of the player. So you could do:
    Code:java
    1. if(cmd.getName().equalsIgnoreCase("top")){
    2. player.sendMessage("§aThe top 5 players are:");
    3. player.sendMessage("§a1st: " + first.getName() + " - " + stats.get(first.getName()));
    4. player.sendMessage("§a2st: " + second.getName() + " - " + stats.get(second.getName()));
    5. player.sendMessage("§a3rd: " + third.getName() + " - " + stats.get(third.getName()));
    6. player.sendMessage("§a4th: " + fourth.getName() + " - " + stats.get(fourth.getName()));
    7. player.sendMessage("§a5th: " + fifth.getName() + " - " + stats.get(fifth.getName()));
    8. return true;
    9. }
     
  23. Offline

    The Fancy Whale

    DonkeyTeeth2013 Sorry now I am even more lost. How would I take it out of the method? And remove a key?
     
  24. Loop through your Map, check for the highest value, then check for a value that is less than or equal to(without 2nd's name), repeat this process.
     
  25. Offline

    DonkeyTeeth2013

    The Fancy Whale
    Instead of declaring the hashmap inside the method, put it at the top of the class like this instead:
    Code:java
    1. public HashMap<String, Integer> stats = new HashMap<String, Integer>();

    and to remove a key, just do this:
    Code:java
    1. stats.remove(player.getName());
     
  26. Offline

    The Fancy Whale

    Can you link me to any java docs demonstrating this? I have never really worked with hashmaps before.

    Do I have to dedicate a class to that then?

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

    DonkeyTeeth2013

    The Fancy Whale The HashMap javadoc. You don't really need to dedicate an entire class to it if you don't want to.
    Either way, your class needs to start out like this:
    Code:java
    1. package some.package;
    2.  
    3. import everything.you.need;
    4.  
    5. public class SomeClass extends JavaPlugin{ //extend JavaPlugin if its your main class
    6.  
    7. public HashMap<String, Integer> stats = new HashMap<String, Integer>();

    Then to get the top 5:
    Code:java
    1. public Player getHighestPlayer(){
    2. HashMap<String, Integer> stats = new HashMap<String, Integer>();
    3. for(String player : getConfig().getKeys(false)){
    4. stats.put(player, getConfig().getInt(player + ".stats"));
    5. }
    6.  
    7. String max = null;
    8. int maxValueInMap=(Collections.max(stats.values()));
    9. for (Entry<String, Integer> entry : stats.entrySet()) {
    10. if (entry.getValue()==maxValueInMap) {
    11. max = entry.getKey();
    12. }
    13. }
    14. Player player = Bukkit.getPlayer(max);
    15. return player;
    16. }
    17.  
    18. public List<Player> getTopFive(){
    19.  
    20. List<Player> players = new ArrayList<Player>();
    21.  
    22. Player first = getHighestPlayer(); //get the highest player
    23. players.add(first); //add the player to the list
    24. stats.remove(first); //remove the player from stats
    25.  
    26. Player second = getHighestPlayer(); //get the next highest player
    27. players.add(second); //add to list
    28. stats.remove(second); //remove from stats
    29.  
    30. //etc..
    31.  
    32. return players;
    33.  
    34. }
    35.  
    36. public Player getTopPlayer(int place){
    37. if(place > 5) //you don't have places larger than 5 so you don't want people to ask for those
    38. return getTopFive().get(place - 1); //get the corresponding place in the list (java starts at zero so you subtract 1)
    39. }


    Just continue the code from getTopFive(), and then all you have to do to get a certain player is getTopPlayer(place)
    So if you wanted the 3rd place player, you do: getTopPlayer(3);
    I inserted a few comments so you can tell what each thing does
     
    The Fancy Whale likes this.
  28. Offline

    The Fancy Whale

    DonkeyTeeth2013 That is working perfectly except I still can't use the variables. Again thanks so much!
     
  29. Offline

    GeorgeeeHD

    when i use the getTopPlayer method, it always returns the same player, no matter what their score is

    edit:

    I think this is because of this:

    Code:java
    1. for(String player : Main.getPlugin().getConfig().getKeys(false)){
    2. stats.put(player, Main.getPlugin().getConfig().getInt(player + ".Kills"));
    3. }


    every time the getHighestPlayer() method is called, it re adds all the players back in, so everytime you do this, Player first = getHighestPlayer(); it readds the players back in and stats.remove(first); is pointless. Not sure how to fix tho :/
     
Thread Status:
Not open for further replies.

Share This Page