001 package org.bukkit.conversations;
002
003 import org.bukkit.Server;
004 import org.bukkit.plugin.Plugin;
005
006 /**
007 * An InactivityConversationCanceller will cancel a {@link Conversation} after
008 * a period of inactivity by the user.
009 */
010 public class InactivityConversationCanceller implements ConversationCanceller {
011 protected Plugin plugin;
012 protected int timeoutSeconds;
013 protected Conversation conversation;
014 private int taskId = -1;
015
016 /**
017 * Creates an InactivityConversationCanceller.
018 *
019 * @param plugin The owning plugin.
020 * @param timeoutSeconds The number of seconds of inactivity to wait.
021 */
022 public InactivityConversationCanceller(Plugin plugin, int timeoutSeconds) {
023 this.plugin = plugin;
024 this.timeoutSeconds = timeoutSeconds;
025 }
026
027 public void setConversation(Conversation conversation) {
028 this.conversation = conversation;
029 startTimer();
030 }
031
032 public boolean cancelBasedOnInput(ConversationContext context, String input) {
033 // Reset the inactivity timer
034 stopTimer();
035 startTimer();
036 return false;
037 }
038
039 public ConversationCanceller clone() {
040 return new InactivityConversationCanceller(plugin, timeoutSeconds);
041 }
042
043 /**
044 * Starts an inactivity timer.
045 */
046 private void startTimer() {
047 taskId = plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
048 public void run() {
049 if (conversation.getState() == Conversation.ConversationState.UNSTARTED) {
050 startTimer();
051 } else if (conversation.getState() == Conversation.ConversationState.STARTED) {
052 cancelling(conversation);
053 conversation.abandon(new ConversationAbandonedEvent(conversation, InactivityConversationCanceller.this));
054 }
055 }
056 }, timeoutSeconds * 20);
057 }
058
059 /**
060 * Stops the active inactivity timer.
061 */
062 private void stopTimer() {
063 if (taskId != -1) {
064 plugin.getServer().getScheduler().cancelTask(taskId);
065 taskId = -1;
066 }
067 }
068
069 /**
070 * Subclasses of InactivityConversationCanceller can override this method
071 * to take additional actions when the inactivity timer abandons the
072 * conversation.
073 *
074 * @param conversation The conversation being abandoned.
075 */
076 protected void cancelling(Conversation conversation) {
077
078 }
079 }