Creating a Delay between If Statements (After the player leaves).

Discussion in 'Plugin Development' started by kayc01, Dec 2, 2014.

Thread Status:
Not open for further replies.
  1. Hey guys, quick problem... i am hoping..

    So, the plan is when a player with a certain permission logs out, it displays a certain message(works).. then on top of that it needs to check after they have left if anyone else on the server has the permission. If not, do stuff.

    This is what i have so far (the schedular part defiantly does not work because it does not allow If statements, it seems..):

    Code:java
    1. for (Player ap : getServer().getOnlinePlayers()) {
    2.  
    3. if (ap.hasPermission("pixelgym.gym1")) {
    4. foundLeader1 = true;
    5. }
    6. if (ap.hasPermission("pixelgym.gym2")) {
    7. foundLeader2 = true;
    8.  
    9. }
    10.  
    11. }
    12.  
    13. if (p.hasPermission("pixelgym.gym1")) {
    14. scheduler.scheduleSyncDelayedTask(this, new Runnable() {
    15. public void run() {
    16. if (!foundLeader1) {
    17. Bukkit.broadcastMessage(ChatColor.DARK_GRAY
    18. + "["
    19. + ChatColor.AQUA
    20. + getConfig().getString("config.title")
    21. + ChatColor.DARK_GRAY
    22. + "] "
    23. + ChatColor.translateAlternateColorCodes('&',
    24. getConfig().getString("config.gym1colour"))
    25. + "The " + getConfig().getString("config.gym1")
    26. + "Gym is now " + ChatColor.RED + "Closed");
    27. getConfig().set("config.gym1stat", "Closed");
    28. this.board.resetScores(Bukkit.getOfflinePlayer(ChatColor
    29. .translateAlternateColorCodes('&', getConfig()
    30. .getString("config.gym1colour"))
    31. + getConfig().getString("config.gym1")));
    32. }
    33. }
    34. }, 20L);
    35. }


    NOTE:
    p = Player that logs out
    ap = All players on the server.

    So the problem is, it does not allow if's inside the Scheduler. But without a delay, the "If (!foundLeader1)" will still look at the player leaving the server unless there is a delay. Supposedly.

    Because the player logging out will still be within "ap" (all players on the server). Which is what foundLeader1 looks through to have a certain permission.

    So, i need it to test if the player logging out has the permission, if they do... then afterwards look at all the other players to see if they do also. If not then do something.

    Basically a test to see if they are the last online on the server to have a permission.

    Thanks :D
     
  2. Offline

    mine-care

    Few things,
    1. sheduler accepts ifs,
    2. This code:
    Code:java
    1. if (p.hasPermission("pixelgym.gym1")) {
    2. scheduler.scheduleSyncDelayedTask(this, new Runnable() {
    3. public void run() {
    4. if (!foundLeader1) {
    5. Bukkit.broadcastMessage(ChatColor.DARK_GRAY
    6. + "["
    7. + ChatColor.AQUA
    8. + getConfig().getString("config.title")
    9. + ChatColor.DARK_GRAY
    10. + "] "
    11. + ChatColor.translateAlternateColorCodes('&',
    12. getConfig().getString("config.gym1colour"))
    13. + "The " + getConfig().getString("config.gym1")
    14. + "Gym is now " + ChatColor.RED + "Closed");
    15. getConfig().set("config.gym1stat", "Closed");
    16. this.board.resetScores(Bukkit.getOfflinePlayer(ChatColor
    17. .translateAlternateColorCodes('&', getConfig()
    18. .getString("config.gym1colour"))
    19. + getConfig().getString("config.gym1")));
    20. }
    21. }
    22. }, 20L);
    23. }

    Is not contained in any class and it is kinda confusding :#

    3. it is a good idea to use local varibales (booleans) and also it is a even better idea not to use variables close in name like variable1 and variable2 because weird messups can happend
    4. any errors? please provide them.
    Good luck
     
  3. Offline

    SyTeck

    All the statements inside run() has to be final, meaning they can not be changed after setting the value.

    Written by hand, but should give you the idea.
    Code:java
    1. public void onPlayerQuitEvent(PlayerQuitEvent event) {
    2.  
    3. Player player = event.getPlayer();
    4. final boolean hasPerm = player.hasPermission("your.permission.node");
    5.  
    6. if(hasPerm == true) {
    7.  
    8. Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    9.  
    10. @Override
    11. public void run() {
    12.  
    13. for(Player p1: Bukkit.getOnlinePlayers()) {
    14.  
    15. if(!p1.hasPermission("your.permission.node")) {
    16.  
    17. p1.sendMessage("your message");
    18.  
    19. }
    20. }
    21. }
    22. }, 20L);
    23. }
    24. }


    This checks if the desired player has permission, and if he do it executes a delayed task which will loop through all players and check if they have permission, if not it will send them a message.

    Please tell me if I got something wrong.
     
  4. Offline

    mythbusterma

    kayc01

    So what exactly does "it does not allow if's inside the Scheduler" mean? The Scheduler is an Object that accepts Runnables and schedules them for execution in synchronization with the server.

    I'm just going to assume you meant "it does not allow if-statements inside the anonymous Runnable," which it, in fact, does. There is no reason it wouldn't, the Runnable is simply an anonymous inner class like any other, and has all the properties of a normal class except a name.

    You should also be getting an error on "this.board" because in that context "this" refers to the Runnable, and not whatever class it's in.

    Use meaningful variable names so that we can actually understand what you're trying to do, rather than "p" and "ap."

    SyTeck It's closer than what he had, but you don't need to compare boolean values to true.
     
    mine-care likes this.
  5. Offline

    SyTeck

    I know, just in case he didn't know.
     
  6. Offline

    mine-care

    mythbusterma :eek: you sniped me... i dont have anything else to say lol =)
     
  7. O

    Okay, miss understanding...
    It accept's If's, i guess but the boolean is not final. It turns out..

    And yes, i do... unfortunately get an error on this.board... But was going to do one thing at a time...

    Any idea's?
    I kinda of get what SyTeck has given me, but you might know how to solve both of these problems.

    Thanks again :)
     
  8. Offline

    SyTeck

    Show us the errors?

    Edit: is this.board a final statement? ALL statements inside run() has to be final.
     

  9. Eclipse Errors? On this.board :

    board cannot be resolved or is not a field
    Seems pretty straight forward but its kind of useless having a scheduler if this.board can't work. It is used in the whole of the plugin for the scoreboard.

    I don't have this.board set as a final, but thats not the error. Its just that the Runnable is called (this, new Runnable).

    Any way to avoid this?
     
  10. Offline

    TGRHavoc

    kayc01
    Using the "this" inside of the Runnable refers to the runnable and not the super class. You will need to make sure that "board" is defined inside the super class and just use it by doing "board.whatever()".
     
  11. Offline

    SyTeck

    Sniped. ^ :)

    "Its just that the Runnable is called (this, new Runnable)." don't get that sentence, mind explaining a little?

    I see that you are using "this.board" at Line 28, this means the class you are calling from, and don't take my word for it but you aren't calling from your main class when inside the run() method, which is from the Runnable class.

    So "this" wouldn't work as it wouldn't exist in that class, try removing "this" and see if it changes anything.
     
  12. TGRHavoc Yes, thank you that worked.
    Also SyTeck for saying the same thing :D

    I am using the first code you gave me and everything seems ok so far. This is that part:

    Code:java
    1. final boolean hasPerm1 = p.hasPermission("pixelgym.gym1");
    2.  
    3. if(hasPerm1 == true) {
    4.  
    5. Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    6.  
    7. @Override
    8. public void run() {
    9.  
    10. for(Player p1: Bukkit.getOnlinePlayers()) {
    11.  
    12. if(!p1.hasPermission("pixelgym.gym1")) {
    13. Bukkit.broadcastMessage(ChatColor.DARK_GRAY
    14. + "["
    15. + ChatColor.AQUA
    16. + getConfig().getString("config.title")
    17. + ChatColor.DARK_GRAY
    18. + "] "
    19. + ChatColor.translateAlternateColorCodes('&',
    20. getConfig().getString("config.gym1colour"))
    21. + "The " + getConfig().getString("config.gym1")
    22. + "Gym is now " + ChatColor.RED + "Closed");
    23. getConfig().set("config.gym1stat", "Closed");
    24. board.resetScores(Bukkit.getOfflinePlayer(ChatColor
    25. .translateAlternateColorCodes('&', getConfig()
    26. .getString("config.gym1colour"))
    27. + getConfig().getString("config.gym1")));
    28. }
    29. }
    30. }
    31. }, 20L);
    32. }
    33. }


    No error's within Eclipse. Just wanted you guys to check over it before hand to make sure it all looks good :)
    Thanks for the help so far btw. <3
     
  13. Offline

    SyTeck

    Np, and just as you know, I used if(hasPerm1 "== true" ) { that part just to demonstrate that you were comparing to true, you can do this if(hasPerm1) { and it will still compare to true.
     

  14. Awesome, i have changed it.
    One final question.. so i will need this routine a few times (will just copy and paste it)

    Everything can be the same right?

    Other than obviously the permission it is checking against, the hasPerm1 = hasPerm2, etc... and what it actually does. But stuff like...

    Code:java
    1. for(Player p1: Bukkit.getOnlinePlayers()) {


    Can be the same. Correct?
     
  15. Offline

    SyTeck


    Copying is never good, even experienced coders can fail while doing so.

    If you have to reuse your code alot I recommend that you create a method for it.
     

  16. SyTeck, Yeah.. so basically it spams chat.
    It displays both gym's as closed for the amount of players that are on the server...
    I know that is caused by the

    Code:java
    1. for(Player p1: Bukkit.getOnlinePlayers()) {


    However, taking that out of the schedular causes lots of error's within eclipse.

    And the problem is, i need them to be unique (why i am having to copy and paste it)
    For each different permission that needs to be checked. :L

    Ok, so here are some updates...
    The reason it spammed before hand is because i had it as bukkit.broadcastMessage instead of p1.sendMessage.
    So it was sending the one broadcast for the amount of online players.

    However we still have a problem...

    Here is what it currently looks like:

    Code:java
    1. final boolean hasPerm1 = p.hasPermission("pixelgym.gym1");
    2. final boolean hasPerm2 = p.hasPermission("pixelgym.gym2");
    3.  
    4. if(hasPerm1) {
    5.  
    6. Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    7.  
    8. @Override
    9. public void run() {
    10.  
    11. for(Player p1: Bukkit.getOnlinePlayers()) {
    12.  
    13. if(!p1.hasPermission("pixelgym.gym1")) {
    14. p1.sendMessage(ChatColor.DARK_GRAY
    15. + "["
    16. + ChatColor.AQUA
    17. + getConfig().getString("config.title")
    18. + ChatColor.DARK_GRAY
    19. + "] "
    20. + ChatColor.translateAlternateColorCodes('&',
    21. getConfig().getString("config.gym1colour"))
    22. + "The " + getConfig().getString("config.gym1")
    23. + "Gym is now " + ChatColor.RED + "Closed");
    24. getConfig().set("config.gym1stat", "Closed");
    25. board.resetScores(Bukkit.getOfflinePlayer(ChatColor
    26. .translateAlternateColorCodes('&', getConfig()
    27. .getString("config.gym1colour"))
    28. + getConfig().getString("config.gym1")));
    29. }
    30. }
    31. }
    32. }, 20L);
    33. }
    34.  
    35. if(hasPerm2) {
    36.  
    37. Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    38.  
    39. @Override
    40. public void run() {
    41.  
    42. for(Player p1: Bukkit.getOnlinePlayers()) {
    43.  
    44. if(!p1.hasPermission("pixelgym.gym2")) {
    45. p1.sendMessage(ChatColor.DARK_GRAY
    46. + "["
    47. + ChatColor.AQUA
    48. + getConfig().getString("config.title")
    49. + ChatColor.DARK_GRAY
    50. + "] "
    51. + ChatColor.translateAlternateColorCodes('&',
    52. getConfig().getString("config.gym2colour"))
    53. + "The " + getConfig().getString("config.gym2")
    54. + "Gym is now " + ChatColor.RED + "Closed");
    55. getConfig().set("config.gym2stat", "Closed");
    56. board.resetScores(Bukkit.getOfflinePlayer(ChatColor
    57. .translateAlternateColorCodes('&', getConfig()
    58. .getString("config.gym2colour"))
    59. + getConfig().getString("config.gym2")));
    60. }
    61. }
    62. }
    63. }, 20L);
    64. }
    65.  
    66. }
    67.  


    SyTeck. Using your code, that you gave me...
    It sends the message to anyone without the permission. Not check if anyone else has it or not and then, if they do.. do not send the message or reset the scoreboard.

    If you understand that.
    So, where as currently it is sending the message to ANYONE who does NOT have the permission:

    Code:java
    1. if(!p1.hasPermission("pixelgym.gym1")) {


    and resetting the scoreboard no matter what..

    When i want it to be checking IF someone else HAS the permission, IF someone else DOES have the permission. Then do NOT send the message to ANYONE or reset the scoreboard.

    To me, the code looks like it should work. However it seems like it is getting confused as such by NOT CHECKING and JUST SENDING the message to ANYONE that does NOT have the permission.

    Any further help is greatly appreciated.

    Thanks! :)

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

    Jaaakee224

  18. Jaaakee224 Yes i have, however it is not going to help me solve this problem...
    I need specific help for this.. like i have been getting in this thread.
     
  19. Offline

    MajorSkillage

    Lol the first thing i thought on here as soon as i saw was
    Code:
    public class Main extends JavaPlugin implements Listener{
        ArrayList<Player> al = new ArrayList<Player>();
        public void onEnable(){
            getServer().getPluginManager().registerEvents(this, this);
        }
        @EventHandler
        public void onJoin(PlayerJoinEvent e){
            al.add(e.getPlayer());
        }
        @EventHandler
        public void onPlayerQuit(PlayerQuitEvent e){
            al.remove(e.getPlayer());
            for(int i = 0; i < al.size(); i++){
                if(e.getPlayer().hasPermission("the perm node")){
                if(al.get(i).hasPermission("the perm node")){
                    //then something here happens
                }
                } else if(e.getPlayer().hasPermission("a different perm node")){
                    if(al.get(i).hasPermission("the different perm node")){
                        //then something else will happen
                        //you could also make an ArrayList of the permission nodes and make it easier then this :)
                    }
                }
            }
        }
    }
    }
    But when i thought about it
    Code:
    public class Main extends JavaPlugin implements Listener{
        public void onEnable(){
            getServer().getPluginManager().registerEvents(this, this);
        }
        @EventHandler
        public void onPlayerQuit(PlayerQuitEvent e){
            if(e.getPlayer().hasPermission("some nub perm")){
            for(Player P : getServer().getOnlinePlayers()){
                if(P.hasPermission("some nub perm")){
                   
                }
            }
            }
        }
    }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 29, 2016
  20. Can you explain the 2nd one a bit? It looks like it is checking if the other players have the permission, and if they do.. then do something. However i want it to be IF NO one ELSE has the permission, then do something.
    adding a ! into "if(P.hasPermission("some nub perm")){" would work?

    Also remember, the delay is required. Because it will still look at the player leaving as having the permission if i don't get it to look 1 second later. (After they have left).

    I would head more towards the first code you gave me because it is removing the leaving player, at least it looks like.
    Am i correct?
    Thanks
     
  21. Offline

    Rocoty

    You really shouldn't have to use a scheduled task for this problem. Remember you can check the current player in the loop up against the player who quit.
     
    AdamQpzm likes this.
  22. kayc01 What you'd want to do is store a boolean, and the loop over the online players, checking each one if they have the permission. If a player has the permission, toggle the boolean value and break the loop. At the end of the loop (be it through you stopping it or it running out of Players), check the boolean value. If it has changed, then there is at least one player with said permission. If it has not changed, there are no players with said permission.

    You also wouldn't need the delay for this - you could simply check with the player from the loop and the player leaving are one and the same. :) (This point was ninja'd by Rocoty :()
     
    Rocoty likes this.
  23. Would you be able to cough up the code ? :D (An Example) The best you can please.
    I am about to head out to college in 1 hour so copy/paste with a few changes would really help me out. Time wise and make sure it is done correctly.
    Knowing me, i would get it wrong.

    Thank you very much! :D
     
  24. kayc01 Won't spoon feed but here's the sort of thing you want to do. Copying & pasting this code definitely won't work, though ;)

    Code:
    boolean b = nope
    for every online player
        if the player isn't the one leaving, and has the permission "cool"
            b is now yep
    if b isn't nope
        say b has changed! :O
    
     
  25. Ok, the only bit i am getting confused on is:

    if the player isn't the one leaving, and has the permission "cool"
    I can't get my head around it. Like, where to call to check if it is not the player logging out.
    How do i check this, i am guessing it would be to do with the onQuitEvent. Which is "p" so something like if(!p... something) xD

    I can't think straight with this... lol
    It also sounds like what i already had at the beginning:

    Code:java
    1. boolean foundLeader1 = false;
    2. boolean foundLeader2 = false;
    3. for (Player ap : getServer().getOnlinePlayers()) {
    4.  
    5. if (ap.hasPermission("pixelgym.gym1")) {
    6. foundLeader1 = true;
    7. }
    8. if (ap.hasPermission("pixelgym.gym2")) {
    9. foundLeader2 = true;


    But i veered away from this because i thought i would need a delay to make sure it is not looking at the player that is leaving.. :L
    Also i need to either copy and paste or create a routine because i have to do this for 32 different permissions... lol
     
  26. Offline

    mythbusterma

    kayc01

    You can just check to make sure that the Player you found isn't the one that is leaving, using a simple equality check. Are nested if-statements really that difficult?
     
  27. Well, sorry... but my confusion is on how to make the leaving player not get counted to look at for allOnlinePlayers().

    Code:java
    1. onPlayerQuit = playerleaving
    2. getOnlinePlayers = onlineplayers
    3.  
    4. if(playerleaving.hasPermission("pixelgym.gym1") {
    5. for onlineplayers
    6. if (!onlineplayers.hasPermission("pixelgym.gym1") {
    7. bukkit.broadcastMessage("Gym1 closed")
    8. }
    9. else {
    10. //nothing
    11. }
    12.  
    13. else {
    14. //nothing
    15. }
    16.  
    17. }

    Thats what i can think of, but i need a way remove playerleaving from allplayers before it checks
     
  28. Offline

    mythbusterma

    kayc01

    ..............

    I honestly don't understand what you're trying to do there. I don't know how it can be made any simpler than what AdamQpzm has already posted. Reread his post and try again.
     
    AdamQpzm likes this.
  29. if the player isn't the one leaving, and has the permission "cool"
    Is what i do not get.. How do i figure if it is the player that is not leaving.
    Infact now i read over it, none of it is making sense to me...

    Instead of telling me how to do something without actually writing the code is not really helping me. I have not been coding too long and is just making it take longer...

    So if you can please, do this for me. I would be very grateful.
    Using my code, turn it into something that would work for checking WHEN a person with a CERTAIN permission node LEAVES, it then checks EVERYONE ELSE on the server (NOT him). If NO ONE ELSE has the same permission node, do something.
    And then maybe an example how i could repeat the process for the other permissions i need to check (exact same things need to be checked).

    Thank you!!! :p
     
  30. Offline

    SyTeck

    Mind updating me on what you got so I can continue helping you?
     
Thread Status:
Not open for further replies.

Share This Page