Fetching list by UUID turns out null

Discussion in 'Plugin Development' started by excusemyluck, Aug 6, 2014.

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

    excusemyluck

    Hello Bukkit Developers! I have a problem and I don't know why it is happening. Let's walk through it.

    First we will start with the code which can be located here: http://pastebin.com/Z8pxZ0F1

    Second, the problem.
    When a player is added to a hitlist, the plugin gets the UUIDs of both players, adds the uuid of the person being added to a list that will be put into a hashmap. Then the hashmap is updated with the new information. I am trying to get the list and send it in a message to a player (the player checking who is on their list). When I do so, the list returns null.

    ** NOTE **
    I HAVE CHECKED IF THE LIST IS NULL, I JUST REMOVED IT FOR NOW!

    I'm not sure why the list is returning back null and I have checked my code multiple times. Thank you for any help you may be able to contribute in advance!
     
  2. Offline

    Dragonphase

    excusemyluck

    First, when you add or remove a UUID from the list, you check if this list is null OR doesn't contain the player to be added. If it isn't null and doesn't contain the player, it creates a new List (thus, any other players stored in the list will be removed and the list will only ever contain one UUID.)

    Second, you don't need to remove the entry from the map to store it with the updated list, just use .put again, it will replace the current value associated to the key (no duplicate entries within a HashMap.)

    Third, you should initialize your fields within a constructor. I see no reason to initialize the HashMap within the class body unless it's constant (static final), which you would not need in this situation. As Garris0n pointed out, your prefix does appear to be constant, so you could make it public static final.

    Finally, you could do something like this:

    Code:java
    1. hitlistMap = new HashMap<UUID, List<UUID>>();
    2.  
    3. //In your add method:
    4.  
    5. if (!hitlistMap.containsKey(uuidOfAdding))
    6. hitlistMap.put(uuidOfAdding, new ArrayList<UUID>());
    7.  
    8. hitlistMap.get(uuidOfadding).add(uuidOfAdded);
    9.  
    10. //In your remove method:
    11.  
    12. if (hitlistMap.containsKey(uuidOfRemoving)){
    13. if (hitlistMap.get(uuidOfRemoving).contains(uuidOfRemoved))
    14. hitlistMap.get(uuidOfRemoving).remove(uuidOfRemoved);
    15. }
     
    Garris0n likes this.
  3. Offline

    Garris0n

    I can only assume it's because you haven't added the list to the map...

    Actually, that prefix looks to actually be a constant, so it should in fact be static and final (and renamed in all caps with words separated by underscores).
     
    Dragonphase likes this.
  4. Offline

    Dragonphase

  5. Offline

    Garris0n

    Dragonphase Noting your edit, it wouldn't have to be public for any reason if it's only in that class.
     
  6. Offline

    Dragonphase

    Garris0n

    True, force of habit and assuming he'd be using the prefix elsewhere in his project :)
     
  7. Offline

    excusemyluck

    Dragonphase Garris0n
    I made the edits that both of you said should be made, but my list is still returning null. Is there anything I'm really missing here that I should be doing? And thank you both for the help!
     
  8. Offline

    Dragonphase

    excusemyluck

    Out of interest, where are you calling your methods from? Do you create multiple instances of HitlistManager whenever you attempt to issue one of those methods?
     
  9. Offline

    Garris0n

    Post the edited code, and include all relevant code this time (i.e. the part you're testing with as well).
     
  10. Offline

    excusemyluck

  11. Offline

    Garris0n

    So where are you calling the method that adds the list to the map?
     
  12. Offline

    excusemyluck

    That would be my add command. I don't want to flood you with another class, but here is the section of code that calls the add method:

    Code:java
    1. if (args.length == 2) {
    2. hlm.addToHitlist(player, Bukkit.getServer().getPlayer(args[1]));
    3. } else {
    4. player.sendMessage(phl.prefix + ChatColor.RED + "Usage: /phl add <username>");
    5. }
     
  13. Offline

    Garris0n

    That was pretty much exactly what I meant, actually :p
     
  14. Offline

    excusemyluck

    I had the feeling that I was doing that. Sorry if it's annoying, at this point I'll give you the relevant code, like you asked for earlier. :p
     
  15. Offline

    Dragonphase

    excusemyluck

    In your C_List.java class, where you are calling hlm.listPlayersOnHitlist(player):
    Code:java
    1. private HitlistManager hlm = new HitlistManager();


    hlm is a new instance. You should create one instance of it, in your plugin for example, and use plugin.getHitlistManager()
     
  16. Offline

    Garris0n

    No, what I meant was you should just post all relevant code (as in the entire classes) :p

    I should've worded that response better.

    I'm already fairly sure I know what the problem is, I just figure it's best to make sure, which requires that other command's class.
     
  17. Offline

    excusemyluck

    After my permission and argument checks:
    Code:java
    1. if (args.length == 1) {
    2. hlm.listPlayersOnHitlist(player);
    3. } else {
    4. player.sendMessage(phl.prefix + ChatColor.RED + "Usage: /phl list");
    5. }


    What class do you need?
     
  18. Offline

    Garris0n

    The class from what you just posted :p

    I'm next to positive that Dragonphase is right, I just never say until I'm actually sure.
     
  19. Offline

    Dragonphase

    excusemyluck

    You misunderstand me. The HitlistManager object within your C_List class is a new instance of HitlistManager. This means that any other instance of the HitlistManager you created and made changes to will not apply to the one within your C_List class.

    Most people would get frustrated at this point, and create one static HitlistManager, which is bad.

    Create one HitlistManager inside your plugin's main class, create a getter for it (getHitlistManager()), and use plugin.getHitlistManager() for anything related to modifying or retrieving data from HitlistManager.
     
    Garris0n likes this.
  20. Offline

    excusemyluck

    http://pastebin.com/8byXiwfU
    There you go :D

    Something I haven't thought of and something I feel I will do!
     
  21. Offline

    Garris0n

  22. Offline

    excusemyluck

    Well I just made that instance.

    And sorry, here is the add command :(
    http://pastebin.com/hi62HmT6
     
  23. Offline

    Garris0n

    This is getting a bit ridiculous, but, uh...where are you instantiating that?

    (and when I say where I mean the entire class)
     
  24. Offline

    excusemyluck

    You know I'm about to just upload this on github lol.

    And I made the new instance in the main class (which I probably did wrong anyways, but I gave it a shot)...
    http://pastebin.com/u8fbPtze
     
  25. Offline

    Garris0n

    No, they have to have one single HitlistManager. Just one, never create another after that. So save an instance variable in the main class and, whenever you need a HitlistManager, use that getter (which you should modify to return the instance).
     
  26. Offline

    excusemyluck

    Garris0n
    Okay thats an easy fix. And I'm uploading on github now to make this easier (which I'm sorry that I'm making this so hard :()
     
  27. Offline

    Dragonphase

    excusemyluck

    Your getter will return a new instance of a HitlistManager every time you invoke it. You need to create one instance of it, and return that one instance within your getter:

    Code:java
    1. private HitlistManager hitlistManager;
    2.  
    3. public void onEnable(){
    4. //code
    5. hitlistManager = new HitlistManager();
    6. }
    7.  
    8. public HitlistManager getHitlistManager(){
    9. return hitlistManager;
    10. }


    Then, use phl.getHitlistManager(); whenever you need to retrieve it. (Assuming you pass your plugin to the constructors where you need to get the HitlistManager.)
     
  28. Offline

    excusemyluck

  29. Offline

    Garris0n

    Well, does it work now? :p
     
  30. Offline

    excusemyluck

    Garris0n and Dragonphase like this.
Thread Status:
Not open for further replies.

Share This Page