Solved Hashmap saving/retrieving wont work

Discussion in 'Plugin Development' started by Theztc, May 30, 2021.

  1. Offline

    Theztc

    Hi, I am trying to save hashmaps, and it's turning into a nightmare.
    I have a hashmap<UUID, Integer> named "donatorRank" That saves the donator rank level of a player in my plugin. It has no trouble saving onDisable, but I can't get it to load on the onEnable. Here's my code

    Code:
    public void onDisable() {
            Map<String, Integer> dRanks = Maps.newHashMap();
            for(Map.Entry<UUID, Integer> ttt : DonatorRanks.donatorRank.entrySet()){
                String pName = getServer().getOfflinePlayer(ttt.getKey()).getName();
                dRanks.put(pName, ttt.getValue());
            }
            List<String> s = getConfig().getStringList("DonatorRanks");
            for(Map.Entry<String, Integer> entry : dRanks.entrySet()) {
                s.add(entry.getKey() + ":" + entry.getValue());
            }
            this.getConfig().set("DonatorRanks", s);
            this.saveConfig();
        }
    Probably a very inefficient way of saving it but it works and I'm tired so idc.

    Here's my onEnable
    Code:
    public void onEnable() {
    this.saveDefaultConfig();           
    if(getConfig().getConfigurationSection("DonatorRanks") != null) {
                    Set<String> set = getConfig().getConfigurationSection("DonatorRanks").getKeys(false);
                    for(String i : set) {
                        String [] j = i.split(":");
                        UUID u = Bukkit.getServer().getOfflinePlayer(j[0]).getUniqueId();
                        int a = Integer.parseInt(j[1]);
                        DonatorRanks.donatorRank.put(u, a);
                    }
                }
            }
    I guess this is the one part of java that I still can't figure out. I've already tried using runTaskLater to see if it just needed a second and that didn't work. I don't know what the heck is wrong with it. Thanks.
     
    Last edited: May 31, 2021
  2. Offline

    KarimAKL

    @Theztc The method name should be "onEnable," not "OnEnable."
     
  3. Offline

    Theztc

    Typo when I was copying. It's correct in my actual class.
     
  4. Offline

    CraftCreeper6

    @Theztc
    There are many optimizations to be made with your onEnable method.

    Firstly, the second for loop is not necessary, you can compute everything you need in the first for loop.

    Also, you should not be saving your string list like so:
    Code:
    DonatorRanks:
         - TestPlayer:TheirRank
    The YAML in Bukkit is already designed in such a way as to combat this exact issue.

    The correct way would be something along the lines of:

    Code:
    TestPlayer:
          rank: playerrank
    Then using
    Code:
    config#getKeys(false);
    To load the data in onEnable()
     
    Last edited: Jun 1, 2021
  5. Offline

    Theztc

    That way of saving could be used for a lot more hashmaps too looks like. I did say my way was very inefficient :)
    I'll make that change. Thanks.

    However, the problem I have is after reload/reboot my data is not being put back into the hashmap. I'll keep working on it though. Another issue was that My UUID was being saved multiple times, each time I rebooted it added my UUID again (To a new line) with the rank number. That's why I changed to saving strings instead. Any ideas as to why that's happening and how to fix it?
     
  6. Offline

    CraftCreeper6

    @Theztc
    With the newly mentioned method you will just be able to use
    Code:
    config#set("TestPlayer.rank", rank)
    To 'update' the config.
    That will solve the duplicate issue you are having.

    I suggest you update the way you save your YML before I assist you any further, the way you're doing it right now is possible, but not exactly ideal. Someone coming here in the future for assistance would benefit more from an improved system as oppose to one with many flaws.

    Tahg or quote me if you have any issues with updating your saving system.
     
  7. Offline

    Theztc

    @CraftCreeper6
    Here's how I wrote it
    Code:
    public void onDisable() {
            for(Map.Entry<UUID, Integer> dRanks : DonatorRanks.donatorRank.entrySet()) {
                this.getConfig().set(getServer().getOfflinePlayer(dRanks.getKey()).getName() + ".rank" , dRanks.getValue());
            }
            this.saveConfig();
        }
    It seems to be saving exactly as I wanted it to.
    Code:
    Theztc:
      rank: 8
    
    So previously I had it all in one String and then was using .split(":") to separate each value. How would I do it now since it's not saved in the same String? I guess my trouble has always been getting it into the hashmap after the reboot. Thanks for the help so far
     
    Last edited: May 31, 2021
  8. Offline

    Shqep

    You're on the right track already with CraftCreeper6's help.

    I'll just explain with examples:
    Example players.yml:
    Code:
    player1:
      rank: iwi
    player2:
      rank: owo
    player3:
      rank: uwu
    PHP:
    config.getKeys(false); // returns list containing "player1", "player2", "player3"
    config.get("player1.rank"); // returns "iwi"
    config.set("player2.rank""uwu"); // just changes the value

    //There are also predefined methods that casts the object to what you need as such:
    config.get("player1.rank"); // returns an Object, and can be casted to a String
    config.getString("player1.rank"); // returns a String
    // In a nutshell, both are the same, one just does the cast for you.
    That's really it for the basics tbh.
     
  9. Offline

    Theztc

    How would I do the for loop? It's saved as
    Code:
    Player1:
              Rank: 8
    Player2:
              Rank: 1
    Player3:
              Rank: 4
    It's not in the section like it was previously. So if I do config.get(Player) I can get that player's value, but how should my for loop look to grab each player listed? The getConfigurationSection wouldn't work since I don't have a section... Right?
     
  10. Offline

    KarimAKL

    @Theztc You can get the keys by using the root section, which is just an empty string. You can probably also just use #getRoot().
     
  11. Offline

    Theztc

    So I'm trying to do this by doing
    Code:
    if(this.getConfig().getConfigurationSection("") != null) {
                Set<String> set = this.getConfig().getConfigurationSection("").getKeys(false);
                for(String i : set) {
                    //Not Sure what to put here...
                }
            }
    Each player has a config section so I think (Might be wrong lol) the best way to get each one is using that for loop.
    Like @Shqep said I can use config.get(player.rank) but I'm struggling to get each player that's in the config

    EDIT - I tried this in my loop
    Code:
    Integer rank = (Integer) this.getConfig().get(i)
    Configuration c = this.getConfig().getRoot();
    UUID u = Bukkit.getPlayer(c).getUniqueID;
    The integer should be correct, but its seems near impossible to convert Configuration to String. I'm guessing I'm doing something wrong
     
    Last edited: Jun 1, 2021
  12. Offline

    CraftCreeper6

    @Theztc
    Use a for loop to iterate over config#getConfigurationSection("")#getKeys(false), each string will be a different player,
    then use config#get("playername.xyz") to load the values
     
  13. Offline

    Theztc

    I did it like this
    Code:
    if(this.getConfig().getConfigurationSection("") != null) {
                Set<String> set = this.getConfig().getConfigurationSection("").getKeys(false);
                for(String i : set) {
                    Integer a = (Integer) getConfig().get(i + ".rank");
                    DonatorRanks.donatorRank.put(Bukkit.getOfflinePlayer(i).getUniqueId(), a);
                }
            }
    And it works perfectly! Thank you all!
    @CraftCreeper6 @KarimAKL @Shqep
     
    KarimAKL, CraftCreeper6 and Shqep like this.

Share This Page