More efficient way of creating 'channels'?

Discussion in 'Plugin Development' started by xDeeKay, Aug 31, 2014.

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

    xDeeKay

    So I've been using this method for creating channels since forever, and after many times of searching for more efficient ways to do it, I haven't been able to come across one. Right now I'm getting the players message on async player chat, cancelling it, then sending a message to those who have the correct permission.

    Of course this brings up many issues if you have other plugins doing things on the same event. So my question, is there another way?
     
  2. Offline

    hintss

    hint: getRecipients() on asyncplayerchatevent actually has a purpose
     
    xDeeKay likes this.
  3. Offline

    xDeeKay

    hintss Well I'm a derp aren't I? Thanks a bunch.

    hintss I'm getting an error when a player speaks in the channel and there's no one online with permission to see the message.

    Code:java
    1. if (Main.staffChat.contains(player.getName())) {
    2. for (Player p : event.getRecipients()) {
    3. if (!p.hasPermission("permission.to.see")) {
    4. event.getRecipients().remove(p);
    5. }
    6. }
    7. }


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

    coasterman10

    You need to use an Iterator to remove elements while iterating over them.
     
    hintss likes this.
  5. Offline

    teej107

  6. Offline

    xDeeKay

    coasterman10 teej107
    I've never used iterations before, do you know how I would use it for my purpose? The link above was for a world chat, and since the guy didn't explain the code, I'm not sure what I have to change and such.
     
  7. Offline

    yupie_123

    xDeeKay Can you post the stack trace (error on the console)
     
  8. Offline

    teej107


    Code:java
    1. @EventHandler
    2. public void onChat(AsyncPlayerChatEvent event) {
    3. //For loop to iterate through the iterator
    4. for(Iterator<Player> itr = event.getRecipients().iterator(); itr.hasNext();) {
    5. itr.next();
    6. if (shouldPlayerNotRecieveMessage) {
    7. //You can remove things from an iterator while looping through them
    8. //Remove the player from the recipient collection so they won't get the message.
    9. itr.remove();
    10. }
    11. }
    12. }
     
  9. Offline

    fireblast709

    Gnat008 likes this.
  10. Offline

    teej107

  11. Offline

    fireblast709

    teej107 you have to invoke next() before you can use remove() ;3.

    [edit] I see, just a bad copypasta from you :p
     
  12. Offline

    teej107

    Yeah I just now realized that. Fixed my post!
     
  13. Offline

    GreySwordz

    teej107 you can also cancel the event and do
    bukkit.broadcastMessage("text", "some.permission");
     
  14. Offline

    teej107

    Then you run into the issue of thread safety.
     
  15. Offline

    xDeeKay

    teej107 fireblast709 Thanks for the explanations guys, I understand it a little better now. Although this doesn't seem to be working, have I done something wrong? (obviously)

    Code:java
    1. for(Iterator<Player> itr = event.getRecipients().iterator(); itr.hasNext();) {
    2. itr.next();
    3. if (Main.staffChat.contains(player.getName())) {
    4. if (player.hasPermission("permission.to.see")) {
    5. itr.remove();
    6. }
    7. }
    8. }
     
  16. Offline

    teej107

  17. Offline

    xDeeKay

    teej107 When a player speaks in the channel, their message doesn't show to players without "permission.to.see" which is fine, but their message also doesn't show to themselves or people with "permission.to.see".
     
  18. Offline

    teej107

    xDeeKay Make sure the player has the permission, add in a check to see if the current iterated player is the one that is sending the message.
     
  19. Offline

    fireblast709

    xDeeKay you need to check the permission of the Player that itr.next() returns ;3
     
  20. Offline

    xDeeKay

  21. Offline

    fireblast709

  22. Offline

    xDeeKay

    fireblast709
    Code:java
    1. for(Iterator<Player> itr = event.getRecipients().iterator(); itr.hasNext();) {
    2. itr.next();
    3. if (Main.staffChat.contains(player.getName())) {
    4. if (itr.next().getPlayer().hasPermission("permission.to.see")) {
    5. itr.remove();
    6. }
    7. }
    8. }


    Now when a player speaks in the channel, it's broadcast to everyone without permission.to.see, and not those with permission.to.see. When I invert the permission check with ! then the message is broadcast to everyone.
     
  23. Offline

    JBoss925

    It'd be much easier to create channel objects. Then in the channel object do the iteration over the recipients in a chat event so it's customized to the channel.
     
  24. Offline

    teej107

    xDeeKay You are calling itr.next() twice remove one of them. When you remove a player from the recipients, you are preventing them from seeing the message. If players with the permission can see the chat, then you want to remove players without the permission.
     
  25. Offline

    xDeeKay

    teej107 Ahh thank you, removing that itr.next and moving the 'contains' check to the top worked.
     
Thread Status:
Not open for further replies.

Share This Page