Problem with setting players' chat colors using ArrayList<Player>

Discussion in 'Plugin Development' started by GlacialCreeper, Jul 15, 2014.

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

    GlacialCreeper

    I've worked on a plugin today, where you use one of three commands:
    /colorset <color>
    /colorset <player> <color>
    /colorset list

    My problem is that, it confirms that you've changed your chat color, but upon chat, the colors won't show.

    This is all in a separate class, by the way.
    I have 7 array lists, for each color:
    Code:java
    1. private ArrayList<Player> colorBlue = new ArrayList<Player>();
    2. private ArrayList<Player> colorPurple = new ArrayList<Player>();
    3. private ArrayList<Player> colorRed = new ArrayList<Player>();
    4. private ArrayList<Player> colorGold = new ArrayList<Player>();
    5. private ArrayList<Player> colorYellow = new ArrayList<Player>();
    6. private ArrayList<Player> colorAqua = new ArrayList<Player>();
    7. private ArrayList<Player> colorGreen = new ArrayList<Player>();


    Here's my constructor for the class (which implements CommandExecutor and Listener):
    Code:java
    1. public ColorSetExecutor(Plugin p)
    2. {
    3. Bukkit.getServer().getPluginManager().registerEvents(this, p);
    4. }


    /colorset has a chunk of code, for each of the colors, in this format:
    Code:java
    1. if (args[0].equalsIgnoreCase("blue"))
    2. {
    3. player = (Player) sender;
    4.  
    5. if (sender instanceof Player){
    6. colorBlue.add(player);
    7. player.sendMessage(colorSetPlugin+ChatColor.GREEN+"Your chat color has been set to "+colors[0]);
    8. }
    9. else
    10. sender.sendMessage(ChatColor.RED+"Hey, silly, this is for players!");
    11. }


    and then I have a method using AsyncPlayerChatEvent later on:
    Code:java
    1. @EventHandler
    2. public void onPlayerChat(AsyncPlayerChatEvent e)
    3. {
    4. Player chatter = e.getPlayer();
    5. String msg = e.getMessage();
    6.  
    7. //Test for ALL the ArrayLists!
    8. if (colorBlue.contains(chatter))
    9. {
    10. e.setCancelled(true);
    11. chatter.chat(ChatColor.BLUE+msg);
    12. }
    13.  
    14. if (colorPurple.contains(chatter))
    15. {
    16. e.setCancelled(true);
    17. chatter.chat(ChatColor.DARK_PURPLE+msg);
    18. }
    19.  
    20. if (colorRed.contains(chatter))
    21. {
    22. e.setCancelled(true);
    23. chatter.chat(ChatColor.RED+msg);
    24. }
    25.  
    26. if (colorGold.contains(chatter))
    27. {
    28. e.setCancelled(true);
    29. chatter.chat(ChatColor.GOLD+msg);
    30. }
    31.  
    32. if (colorYellow.contains(chatter))
    33. {
    34. e.setCancelled(true);
    35. chatter.chat(ChatColor.YELLOW+msg);
    36. }
    37.  
    38. if (colorAqua.contains(chatter))
    39. {
    40. e.setCancelled(true);
    41. chatter.chat(ChatColor.AQUA+msg);
    42. }
    43.  
    44. if (colorGreen.contains(chatter))
    45. {
    46. e.setCancelled(true);
    47. chatter.chat(ChatColor.GREEN+msg);
    48. }
    49. }


    The game does tell you that your chat color's been set, so I know that it does indeed add you to an array list. I can't really see the issue, but the console said it can't pass the event to the class, and that it causes a stack overflow (I'm not sure what that means exactly). It says the problem's at line 244 somewhere in the huge exception returned in the console, which is the first "chatter.chat()". Anyone know what could cause this in my code?
     
  2. Offline

    mythbusterma

    It would probably be more practical to add a Metadata tag to each player based on what their color should be.

    However, your stack overflow exception is usually caused by an infinite loop caused by two methods calling each other, for example:

    Code:java
    1. public void b() {
    2. a();
    3. }
    4.  
    5. public void a() {
    6. b();
    7. }


    Calling the "a()" method of the above code would generate an infinite loop and eventually result in a stack overflow error.

    What this would be caused by is that your code effectively calls itself by calling Player#chat(...), which in turn will generate an AsyncPlayerChatEvent, that has another Player#chat(...), which will continue on forever.

    EDIT: GlacialCreeper, you are using an AsyncPlayerChatEvent as if it is synchronous (i.e. run on the main thread), which it is not (as evidenced by the "async" in its name), you should take this into consideration.
     
    AoH_Ruthless likes this.
  3. Offline

    GlacialCreeper


    mythbusterma Wow, I'm impressed, excellent explanation! I used the asynchronous one because the javadocs encouraged using it, but I'm not sure what I should do then. I need to get their message, and get them to chat it in the color they're using, but..hm. Other plugins do the same sort of thing, but how would they have done it? What would you guys suggest I should change?
    EDIT: I found an e.setMessage() method, and it fixes my problem :D although, I would like to know more about what you mean by Metadata tag, as I am not a professional programmer (I'm only 14).

    EDIT: It fixes my problem while I'm on the server, but if I quit and come back it doesn't save your color. I think I'm gonna use a yml file for it.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
Thread Status:
Not open for further replies.

Share This Page