0

I'm trying to use a Bukkit conversation, which already works, yet, when I use TimeUnit.SECONDS.sleep(integer-value), it works once, and then it fails with this error in console: java.lang.InterruptedException: sleep interrupted

When a prompt has been shown and the next is going to be shown the method acceptInput is called. In the first prompt it works all fine, in the other prompts, which are called out of this prompt (the prompt calls a new instance of itself). All works fine except the sleep part. Any ideas to fix this?

Here is my code:

package dbx12.Test1.Tutorial.Prompts;


import java.util.concurrent.TimeUnit;

import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.entity.Player;


public class Text implements Prompt {

    @Override
    public Prompt acceptInput(ConversationContext context, String input) {
        int thisPrompt = (int) context.getSessionData("step");
        context.setSessionData("step", thisPrompt+1);
        Player p = (Player) context.getForWhom();

        boolean type;

        try {
            TimeUnit.SECONDS.sleep(dbx12.Test1.Utils.Prompt_List.delay.get(thisPrompt));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace(); //DEBUG
        }       

        try {
            type = dbx12.Test1.Utils.Prompt_List.promptType.get(thisPrompt+1);
        } catch (Exception e) {
            return new Finish();
        }

        if(dbx12.Test1.Utils.Prompt_List.hasLocation.get(thisPrompt+1) == true)
            p.teleport(dbx12.Test1.Utils.Prompt_List.location.get(thisPrompt+1));

        if(type==true)
        {
            System.out.println("return a text");
            return new Text();
        }
        else
        {
            System.out.println("return a interaction");
            return new Interaction();
        }
    }

    @Override
    public boolean blocksForInput(ConversationContext context) {
        return false;
    }

    @Override
    public String getPromptText(ConversationContext context) {
        return dbx12.Test1.Utils.Prompt_List.promptText.get(context.getSessionData("step"));
    }

}
Jojodmo
  • 23,357
  • 13
  • 65
  • 107
DBX12
  • 1
  • What are you trying to do here? Set a delay? What is this plugin going to be doing? There may be a better way of doing this. – Jojodmo Feb 22 '14 at 19:28
  • I try to show information via prompts. After a certain delay the next prompt is shown. The delay works at the first time, but fails in the next x prompts. I call the next prompt as new instance of this one. – DBX12 Feb 22 '14 at 21:22

1 Answers1

1

sleep will cause your entire server to stop doing anything for x seconds. Instead of sleep, use a SyncDelayedTask:

this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){
    public void run(){
        //what you want to do here
    }
},delayInSeconds * 20);

so, lets say for example you wanted to send test1 to the server, then test2 to the server 5 seconds later, you could use:

int repeats;

public void sendMessages(){
    this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){

    public void run(){
        if(repeats == 0){ //if it's the first time running
            Bukkit.getServer.broadcastMessage("test1");
            repeats++; //add to repeats
            sendMessages(); //call the method again
        }
        else if(repeats == 1){ //if it is the second time being called
            Bukkit.getServer.broadcastMessage("test2");
        }
    }
},5 * 20);//wait 5 seconds 

so with the above code, you could make a method like this:

public void startSendingMessages(){
    repeats = 0;
    sendMessages();
}

Where when you called startSendingMessages(), the test1 would be sent, then, 5 seconds later, test2 would be sent.

The reason we are multiplying the time in seconds by 20, is because it has to be in ticks, or minecraft time, and 1 second = 20 ticks.

There's lots of other scheduler types, like SyncRepeatingTasks. To learn more about them, check out the bukkit JavaDocs: http://jd.bukkit.org/dev/apidocs/, theres also a nice tutorial from bukkit here: http://wiki.bukkit.org/Scheduler_Programming

Jojodmo
  • 23,357
  • 13
  • 65
  • 107
  • This won't work in they way I want. Maybe I wasn't precise enough ;) I want to delay the execution at the point where I used the `try{ TimeUnit.SECONDS.sleep(dbx12.Test1.Utils.Prompt_List.delay.get(thisPrompt)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); //DEBUG } ` So I try to wait until a specified time is over and then I want to return a new "Finish" or "Text" or "Interaction". At the time I return a Prompt this Prompt is shown. So I want to delay the display of this Prompt. – DBX12 Mar 01 '14 at 14:28
  • Sorry for the bad format but stackoverflow cancelled my edits because I went over 5 minutes. Off-topic: A preview or longer time for editing would be nice. – DBX12 Mar 01 '14 at 14:36
  • @DBX12 same principle applies, you could just change the time at the bottom, here: `},5 * 20);` to `the time you want * 20` – Jojodmo Mar 01 '14 at 18:01