Citizens2/main/src/main/java/net/citizensnpcs/commands/NPCCommandSelector.java

130 lines
5.0 KiB
Java

package net.citizensnpcs.commands;
import java.util.List;
import java.util.UUID;
import org.bukkit.command.CommandSender;
import org.bukkit.conversations.Conversable;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.conversations.NumericPrompt;
import org.bukkit.conversations.Prompt;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.command.CommandContext;
import net.citizensnpcs.api.command.CommandMessages;
import net.citizensnpcs.api.command.exception.CommandException;
import net.citizensnpcs.api.command.exception.CommandUsageException;
import net.citizensnpcs.api.command.exception.ServerCommandException;
import net.citizensnpcs.api.command.exception.UnhandledCommandException;
import net.citizensnpcs.api.command.exception.WrappedCommandException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util;
public class NPCCommandSelector extends NumericPrompt {
private final Callback callback;
private final List<NPC> choices;
public NPCCommandSelector(Callback callback, List<NPC> possible) {
this.callback = callback;
choices = possible;
}
@Override
protected Prompt acceptValidatedInput(ConversationContext context, Number input) {
boolean found = false;
for (NPC npc : choices) {
if (input.intValue() == npc.getId()) {
found = true;
break;
}
}
CommandSender sender = (CommandSender) context.getForWhom();
if (!found) {
Messaging.sendErrorTr(sender, Messages.SELECTION_PROMPT_INVALID_CHOICE, input);
return this;
}
NPC toSelect = CitizensAPI.getNPCRegistry().getById(input.intValue());
try {
callback.run(toSelect);
} catch (ServerCommandException ex) {
Messaging.sendTr(sender, CommandMessages.MUST_BE_INGAME);
} catch (CommandUsageException ex) {
Messaging.sendError(sender, ex.getMessage());
Messaging.sendError(sender, ex.getUsage());
} catch (UnhandledCommandException ex) {
ex.printStackTrace();
} catch (WrappedCommandException ex) {
ex.getCause().printStackTrace();
} catch (CommandException ex) {
Messaging.sendError(sender, Messaging.tryTranslate(ex.getMessage()));
} catch (NumberFormatException ex) {
Messaging.sendErrorTr(sender, CommandMessages.INVALID_NUMBER);
}
return null;
}
@Override
public String getPromptText(ConversationContext context) {
String text = Messaging.tr(Messages.SELECTION_PROMPT);
for (NPC npc : choices) {
text += "<br> - " + npc.getId();
}
Messaging.send((CommandSender) context.getForWhom(), text);
return "";
}
public static interface Callback {
public void run(NPC npc) throws CommandException;
}
public static void start(Callback callback, Conversable player, List<NPC> possible) {
Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin()).withLocalEcho(false)
.withEscapeSequence("exit").withModality(false)
.withFirstPrompt(new NPCCommandSelector(callback, possible)).buildConversation(player);
conversation.begin();
}
public static void startWithCallback(Callback callback, NPCRegistry npcRegistry, CommandSender sender,
CommandContext args, String raw) throws CommandException {
try {
UUID uuid = UUID.fromString(raw);
callback.run(npcRegistry.getByUniqueIdGlobal(uuid));
return;
} catch (IllegalArgumentException e) {
}
Integer id = Ints.tryParse(raw);
if (id != null) {
callback.run(npcRegistry.getById(id));
return;
}
String name = args.getString(1);
List<NPC> possible = Lists.newArrayList();
double range = -1;
if (args.hasValueFlag("range")) {
range = Math.abs(args.getFlagDouble("range"));
}
for (NPC test : npcRegistry) {
if (test.getName().equalsIgnoreCase(name)) {
if (range > 0 && test.isSpawned()
&& !Util.locationWithinRange(args.getSenderLocation(), test.getEntity().getLocation(), range)) {
continue;
}
possible.add(test);
}
}
if (possible.size() == 1) {
callback.run(possible.get(0));
} else if (possible.size() > 1) {
NPCCommandSelector.start(callback, (Conversable) sender, possible);
}
}
}