mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-12 13:44:14 +01:00
164 lines
4.9 KiB
Java
164 lines
4.9 KiB
Java
package com.comphenix.protocol;
|
|
|
|
import org.bukkit.conversations.Conversation;
|
|
import org.bukkit.conversations.ConversationCanceller;
|
|
import org.bukkit.conversations.ConversationContext;
|
|
import org.bukkit.conversations.ExactMatchConversationCanceller;
|
|
import org.bukkit.conversations.Prompt;
|
|
import org.bukkit.conversations.StringPrompt;
|
|
|
|
/**
|
|
* Represents a conversation prompt that accepts a list of lines.
|
|
*
|
|
* @author Kristian
|
|
*/
|
|
class MultipleLinesPrompt extends StringPrompt {
|
|
/**
|
|
* Represents a canceller that determines if the multiple lines prompt is finished.
|
|
* @author Kristian
|
|
*/
|
|
public static interface MultipleConversationCanceller extends ConversationCanceller {
|
|
@Override
|
|
public boolean cancelBasedOnInput(ConversationContext context, String currentLine);
|
|
|
|
/**
|
|
* Determine if the current prompt is done based on the context, last
|
|
* line and collected lines.
|
|
*
|
|
* @param context - current context.
|
|
* @param currentLine - current (last) line.
|
|
* @param lines - collected lines.
|
|
* @param lineCount - number of lines.
|
|
* @return TRUE if we are done, FALSE otherwise.
|
|
*/
|
|
public boolean cancelBasedOnInput(ConversationContext context, String currentLine,
|
|
StringBuilder lines, int lineCount);
|
|
}
|
|
|
|
/**
|
|
* A wrapper class for turning a ConversationCanceller into a MultipleConversationCanceller.
|
|
* @author Kristian
|
|
*/
|
|
private static class MultipleWrapper implements MultipleConversationCanceller {
|
|
private ConversationCanceller canceller;
|
|
|
|
public MultipleWrapper(ConversationCanceller canceller) {
|
|
this.canceller = canceller;
|
|
}
|
|
|
|
@Override
|
|
public boolean cancelBasedOnInput(ConversationContext context, String currentLine) {
|
|
return canceller.cancelBasedOnInput(context, currentLine);
|
|
}
|
|
|
|
@Override
|
|
public boolean cancelBasedOnInput(ConversationContext context, String currentLine,
|
|
StringBuilder lines, int lineCount) {
|
|
return cancelBasedOnInput(context, currentLine);
|
|
}
|
|
|
|
@Override
|
|
public void setConversation(Conversation conversation) {
|
|
canceller.setConversation(conversation);
|
|
}
|
|
|
|
@Override
|
|
public MultipleWrapper clone() {
|
|
return new MultipleWrapper(canceller.clone());
|
|
}
|
|
}
|
|
|
|
// Feels a bit like Android
|
|
private static final String KEY = "multiple_lines_prompt";
|
|
private static final String KEY_LAST = KEY + ".last_line";
|
|
private static final String KEY_LINES = KEY + ".linecount";
|
|
|
|
private final MultipleConversationCanceller endMarker;
|
|
private final String initialPrompt;
|
|
|
|
/**
|
|
* Retrieve and remove the current accumulated input.
|
|
*
|
|
* @param context
|
|
* - conversation context.
|
|
* @return The accumulated input, or NULL if not found.
|
|
*/
|
|
public String removeAccumulatedInput(ConversationContext context) {
|
|
Object result = context.getSessionData(KEY);
|
|
|
|
if (result instanceof StringBuilder) {
|
|
context.setSessionData(KEY, null);
|
|
context.setSessionData(KEY_LINES, null);
|
|
return ((StringBuilder) result).toString();
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Construct a multiple lines input prompt with a specific end marker.
|
|
* <p>
|
|
* This is usually an empty string.
|
|
*
|
|
* @param endMarker - the end marker.
|
|
*/
|
|
public MultipleLinesPrompt(String endMarker, String initialPrompt) {
|
|
this(new ExactMatchConversationCanceller(endMarker), initialPrompt);
|
|
}
|
|
|
|
/**
|
|
* Construct a multiple lines input prompt with a specific end marker implementation.
|
|
* <p>
|
|
* Note: Use {@link #MultipleLinesPrompt(MultipleConversationCanceller, String)} if implementing a custom canceller.
|
|
* @param endMarker - the end marker.
|
|
* @param initialPrompt - the initial prompt text.
|
|
*/
|
|
public MultipleLinesPrompt(ConversationCanceller endMarker, String initialPrompt) {
|
|
this.endMarker = new MultipleWrapper(endMarker);
|
|
this.initialPrompt = initialPrompt;
|
|
}
|
|
|
|
/**
|
|
* Construct a multiple lines input prompt with a specific end marker implementation.
|
|
* @param endMarker - the end marker.
|
|
* @param initialPrompt - the initial prompt text.
|
|
*/
|
|
public MultipleLinesPrompt(MultipleConversationCanceller endMarker, String initialPrompt) {
|
|
this.endMarker = endMarker;
|
|
this.initialPrompt = initialPrompt;
|
|
}
|
|
|
|
@Override
|
|
public Prompt acceptInput(ConversationContext context, String in) {
|
|
StringBuilder result = (StringBuilder) context.getSessionData(KEY);
|
|
Integer count = (Integer) context.getSessionData(KEY_LINES);
|
|
|
|
// Handle first run
|
|
if (result == null)
|
|
context.setSessionData(KEY, result = new StringBuilder());
|
|
if (count == null)
|
|
count = 0;
|
|
|
|
// Save the last line as well
|
|
context.setSessionData(KEY_LAST, in);
|
|
context.setSessionData(KEY_LINES, ++count);
|
|
result.append(in + "\n");
|
|
|
|
// And we're done
|
|
if (endMarker.cancelBasedOnInput(context, in, result, count))
|
|
return Prompt.END_OF_CONVERSATION;
|
|
else
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public String getPromptText(ConversationContext context) {
|
|
Object last = context.getSessionData(KEY_LAST);
|
|
|
|
if (last instanceof String)
|
|
return (String) last;
|
|
else
|
|
return initialPrompt;
|
|
}
|
|
}
|