Bukkit Delayed Tasks not running in order

Discussion in 'Plugin Development' started by Dragonphase, Feb 23, 2013.

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

    Dragonphase

    What I am trying to do is run a series of commands after the other in order, taking into account any delays that need to happen. The following code will, without delay commands, run all other commands in order:

    Code:java
    1.  
    2. int delay = 0;
    3. String Command = "say I|@delay 25|say II|say III|say IIII|@delay 50|say IIIII|say IIIIII";
    4. String[] Commands = Command.split(Pattern.quote("|"));
    5. for (int j = 0; j < Commands.length; j ++){
    6. if (Commands[j].contains("@delay")){
    7. String[] delayArgs = Commands[j].split(" ");
    8. delay += Integer.parseInt(delayArgs[1]);
    9. }else{
    10. new ScheduledTask(Commands[j]).runTaskLater(plugin, delay);
    11. }
    12. }


    Output:

    Code:
    I
    II
    III
    IIII
    IIIII
    IIIIII
    However, when this change is made:


    Code:java
    1.  
    2. String Command = "say I|@delay 25|say II|say III|say IIII|@delay 50|say IIIII|say IIIIII";


    It does not run the commands after the exact given delay; sometimes it runs as it should with the delays accounted for, but at other times, commands after delays are not run in order. I receive the following output on these occasions:


    Code:
    I
    II
    III
    IIII
    IIIIII
    IIIII
    I have attempted to use a foreach loop here but the for loop I currently have works better. What would be good is to assign a delay value to tasks that carry on to succeeding tasks. If this is possible, or a better workaround is viable, I would love to know.

    Thanks.
     
  2. Why not simply iterate over all commands with the same delay in one task, instead of splitting them into many tasks where the order isn't guarantied?
     
  3. Offline

    Dragonphase

    Because I'm developing a plugin whereby delays can be customized between commands.

    Code:java
    1. public class ScheduledTask extends BukkitRunnable{
    2.  
    3. private String Command;
    4. private CommandSender Sender;
    5. private boolean Op, currentOp;
    6.  
    7. public ScheduledTask(String command){
    8. Command = command;
    9. Sender = Bukkit.getServer().getConsoleSender();
    10. }
    11.  
    12. public ScheduledTask(Player player, String command, boolean op){
    13. Command = command;
    14. Sender = (CommandSender) player;
    15. Op = op;
    16. currentOp = player.isOp();
    17. }
    18.  
    19. @Override
    20. public void run(){
    21. if (Sender instanceof Player){
    22. Player player = (Player) Sender;
    23. if (!currentOp) player.setOp(Op);
    24. player.performCommand(Command);
    25. if (Op) player.setOp(currentOp);
    26. }else{
    27. Bukkit.dispatchCommand(Sender, Command);
    28. }
    29. }
    30. }


    I cannot iterate through each command in the run function here because the plugin needs to set a unique delay for each command. For example:

    /say this command should run first
    delay for 1 second
    /say this command should run second <- total delay: 1 second
    /say this command should run third <- total delay: 1 second
    delay for 1 second
    /say this command should run fourth <- total delay: 2 seconds
    /say this command should run fifth <- total delay: 2 seconds
     
  4. If the delays are consistent you can do it with one task just fine...
    Actually even if they're not consistent you can still do it.

    You're also relying on the in-game chat, which is in a diferent thread I belive, to tell you the order of your executions... print them in server console, that's the way to debug.
     
  5. You didn't got my point. You should put all commands having the same delay in the same task. Means you should generate a new task only when a new delay is needed. Then you can give each task an array of commands to be done in a for each loop instead of doing only one command per task.
     
  6. Offline

    Dragonphase

    I understand you now, thankyou.I will apply this to my plugin now

    I actually did something different but it actually fixed the problem when I least expected it to. Here's what I did:


    Code:java
    1. new ScheduledTask("" + delay + "}" + Commands[j]).runTaskLater(plugin, delay);


    And in the ScheduledTask class, i simply substringed the command to the index of } + 1. This solved the problem when I was actually just trying to find out if the delays were correct. Thankyou for your help though.
     
  7. Why not just use 2 arguments instead of parsing strings ... ?

    new ScheduledTask(delay, commands[j])...
     
  8. +1 for using typed parameters instead of using a String you need to split of and convert.
     
Thread Status:
Not open for further replies.

Share This Page