/*
* This file is part of RPG Items.
*
* RPG Items is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RPG Items is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RPG Items. If not, see <http://www.gnu.org/licenses/>.
*/
package think.rpgitems.commands;
import gnu.trove.map.hash.TCharObjectHashMap;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.SimpleTimeZone;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import think.rpgitems.Plugin;
import think.rpgitems.data.Locale;
import think.rpgitems.item.ItemManager;
import think.rpgitems.item.RPGItem;
abstract public class Commands {
private static HashMap<String, ArrayList<CommandDef>> commands = new HashMap<String, ArrayList<CommandDef>>();
private static TCharObjectHashMap<Class<? extends CommandArgument>> argTypes = new TCharObjectHashMap<Class<? extends CommandArgument>>();
static {
argTypes.put('s', ArgumentString.class);
argTypes.put('i', ArgumentInteger.class);
argTypes.put('f', ArgumentDouble.class);
argTypes.put('p', ArgumentPlayer.class);
argTypes.put('o', ArgumentOption.class);
argTypes.put('n', ArgumentItem.class);
argTypes.put('m', ArgumentMaterial.class);
argTypes.put('e', ArgumentEnum.class);
}
public static void exec(CommandSender sender, String com) {
com = com.trim();
if (com.length() == 0)
return;
String comName;
int pos = com.indexOf(' ');
if (pos == -1) {
comName = com;
} else {
comName = com.substring(0, pos);
}
com = com.substring(pos + 1);
String locale = sender instanceof Player ? Locale.getPlayerLocale((Player)sender) : "en_GB";
ArrayList<CommandDef> command = commands.get(comName);
if (command == null) {
sender.sendMessage(ChatColor.RED + String.format(Locale.get("message.error.unknown.command", locale), comName));
return;
}
if (pos == -1) {
for (CommandDef c : command) {
if (c.arguments.length == 0) {
try {
if (c.handlePermissions || sender.hasPermission("rpgitem"))
c.method.invoke(c.handler, sender);
else
sender.sendMessage(ChatColor.RED + Locale.get("message.error.permission", locale));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
}
// Print usage
if (sender.hasPermission("rpgitem")) {
sender.sendMessage(String.format(ChatColor.GREEN + Locale.get("message.command.usage", locale), comName, Plugin.plugin.getDescription().getVersion()));
for (CommandDef c : command) {
StringBuilder buf = new StringBuilder();
buf.append(ChatColor.GREEN).append('/').append(comName);
for (CommandArgument a : c.arguments) {
buf.append(' ');
if (a.name.length() != 0) {
buf.append(ChatColor.RED);
buf.append(Locale.get("command.info." + a.name, locale));
}
buf.append(a.isConst() ? ChatColor.GREEN : ChatColor.GOLD);
buf.append(a.printable(locale));
}
sender.sendMessage(buf.toString());
}
sender.sendMessage(ChatColor.GREEN + Locale.get("message.command.info", locale));
} else
sender.sendMessage(ChatColor.RED + Locale.get("message.error.permission", locale));
return;
}
ArrayList<String> args = new ArrayList<String>();
while (true) {
int end;
if (com.length() == 0) {
break;
}
boolean quote = false;
if (com.charAt(0) == '`') {
com = com.substring(1);
end = com.indexOf('`');
quote = true;
} else {
end = com.indexOf(' ');
}
if (end == -1) {
args.add(com);
} else {
args.add(com.substring(0, end));
}
if (quote) {
com = com.substring(end + 1);
end = com.indexOf(' ');
}
if (end != -1) {
com = com.substring(end + 1);
} else {
break;
}
}
CommandError lastError = null;
comLoop: for (CommandDef c : command) {
if (c.arguments.length != args.size()) {
if (c.arguments.length != 0 && c.arguments[c.arguments.length - 1] instanceof ArgumentString) {
if (args.size() < c.arguments.length)
continue;
} else {
continue;
}
}
ArrayList<Object> outArgs = new ArrayList<Object>();
outArgs.add(sender);
for (int i = 0; i < c.arguments.length; i++) {
CommandArgument a = c.arguments[i];
if (!a.isConst()) {
if (i == c.arguments.length - 1) {
// Special case for strings so they do not need to be quoted
if (a instanceof ArgumentString) {
StringBuilder joined = new StringBuilder();
for (int j = i; j < args.size(); j++) {
joined.append(args.get(j)).append(' ');
}
args.set(i, joined.toString().trim());
}
}
Object res = a.parse(args.get(i), locale);
if (res instanceof CommandError) {
lastError = (CommandError) res;
continue comLoop;
}
outArgs.add(res);
} else {
ArgumentConst cst = (ArgumentConst) a;
if (!cst.value.equals(args.get(i))) {
continue comLoop;
}
}
}
try {
if (c.handlePermissions || sender.hasPermission("rpgitem"))
c.method.invoke(c.handler, outArgs.toArray());
else
sender.sendMessage(ChatColor.RED + Locale.get("message.error.permission", locale));
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
if (sender.hasPermission("rpgitem")) {
if (lastError != null) {
sender.sendMessage(ChatColor.RED + String.format(Locale.get("message.error.command", locale), lastError.error));
} else {
ArrayList<String> consts = new ArrayList<String>();
comLoop: for (CommandDef c : command) {
for (int i = 0; i < c.arguments.length; i++) {
if (i >= args.size())
break;
CommandArgument a = c.arguments[i];
if (!a.isConst()) {
if (i == c.arguments.length - 1) {
// Special case for strings so they do not need to be quoted
if (a instanceof ArgumentString) {
StringBuilder joined = new StringBuilder();
for (int j = i; j < args.size(); j++) {
joined.append(args.get(j)).append(' ');
}
args.set(i, joined.toString().trim());
}
}
Object res = a.parse(args.get(i), locale);
if (res instanceof CommandError) {
lastError = (CommandError) res;
continue comLoop;
}
} else {
ArgumentConst cst = (ArgumentConst) a;
if (!cst.value.equals(args.get(i))) {
continue comLoop;
} else {
consts.add(cst.value);
}
}
}
}
StringBuilder search = new StringBuilder();
for (String term : consts) {
search.append(term).append(' ');
}
searchHelp(sender, search.toString());
}
} else
sender.sendMessage(ChatColor.RED + Locale.get("message.error.permission", locale));
}
public static List<String> complete(CommandSender sender, String com) {
com = com.trim();
if (com.length() == 0) {
return new ArrayList<String>();
}
String comName;
int pos = com.indexOf(' ');
if (pos == -1) {
comName = com;
} else {
comName = com.substring(0, pos);
}
com = com.substring(pos + 1);
String locale = sender instanceof Player ? Locale.getPlayerLocale((Player)sender) : "en_GB";
ArrayList<CommandDef> command = commands.get(comName);
if (command == null) {
if (pos == -1) {
ArrayList<String> out = new ArrayList<String>();
for (String n : commands.keySet()) {
if (n.startsWith(comName)) {
out.add("/" + n);
}
}
return out;
}
return new ArrayList<String>();
}
ArrayList<String> args = new ArrayList<String>();
while (true) {
int end;
if (com.length() == 0) {
break;
}
boolean quote = false;
if (com.charAt(0) == '`') {
com = com.substring(1);
end = com.indexOf('`');
quote = true;
} else {
end = com.indexOf(' ');
}
if (end == -1) {
args.add(com);
} else {
args.add(com.substring(0, end));
}
if (quote) {
com = com.substring(end + 1);
end = com.indexOf(' ');
}
if (end != -1) {
com = com.substring(end + 1);
} else {
break;
}
}
HashMap<String, Boolean> out = new HashMap<String, Boolean>();
comLoop: for (CommandDef c : command) {
for (int i = 0; i < c.arguments.length; i++) {
CommandArgument a = c.arguments[i];
if (i == args.size() - 1) {
List<String> res = a.tabComplete(args.get(i));
if (res != null) {
for (String s : res) {
out.put(s, true);
}
continue comLoop;
}
} else {
if (!a.isConst()) {
Object res = a.parse(args.get(i), locale);
if (res instanceof CommandError) {
continue comLoop;
}
} else {
ArgumentConst cst = (ArgumentConst) a;
if (!cst.value.equals(args.get(i))) {
continue comLoop;
}
}
}
}
}
ArrayList<String> outList = new ArrayList<String>();
for (String s : out.keySet()) {
outList.add(s);
}
return outList;
}
public static void register(CommandHandler handler) {
Method[] methods = handler.getClass().getMethods();
for (Method method : methods) {
Class<?>[] params = method.getParameterTypes();
CommandString comString = method.getAnnotation(CommandString.class);
if (comString == null) {
continue;
}
if (params.length == 0 || !params[0].isAssignableFrom(CommandSender.class)) {
throw new RuntimeException("First argument must be CommandSender @ " + method.getName());
}
add(comString.value(), method, handler);
}
Collection<ArrayList<CommandDef>> coms = commands.values();
for (ArrayList<CommandDef> c : coms) {
Collections.sort(c);
}
}
private static void add(String com, Method method, CommandHandler handler) {
com = com.trim();
int pos = com.indexOf(' ');
String comName;
if (pos == -1) {
comName = com;
} else {
comName = com.substring(0, pos);
}
CommandDef def = new CommandDef();
def.commandString = com;
def.method = method;
def.handler = handler;
Class<?>[] params = method.getParameterTypes();
if (method.isAnnotationPresent(CommandDocumentation.class)) {
def.documentation = method.getAnnotation(CommandDocumentation.class).value();
} else {
def.documentation = "";
}
if (method.isAnnotationPresent(CommandGroup.class)) {
def.sortKey = method.getAnnotation(CommandGroup.class).value();
} else {
def.sortKey = "";
}
CommandString comString = method.getAnnotation(CommandString.class);
def.handlePermissions = comString.handlePermissions();
if (!commands.containsKey(comName)) {
commands.put(comName, new ArrayList<CommandDef>());
}
commands.get(comName).add(def);
if (pos == -1) {
def.arguments = new CommandArgument[0];
return;
}
com = com.substring(pos + 1);
ArrayList<CommandArgument> arguments = new ArrayList<CommandArgument>();
int realArgumentsCount = 0;
while (true) {
pos = com.indexOf(' ');
String a;
if (pos == -1) {
a = com;
} else {
a = com.substring(0, pos);
com = com.substring(pos + 1);
}
if (a.charAt(0) == '$') { // Variable
String name = "";
if (a.contains(":")) {
String[] as = a.split(":");
name = as[0].substring(1);
a = "$" + as[1];
}
char t = a.charAt(1);
Class<? extends CommandArgument> cAT = argTypes.get(t);
if (cAT == null) {
throw new RuntimeException("Invalid command argument type " + t);
}
CommandArgument arg;
try {
arg = cAT.newInstance();
arg.init(a.substring(3, a.length() - 1));
if (!params[realArgumentsCount + 1].isAssignableFrom(arg.getType())) {
throw new RuntimeException("Type mismatch for " + method.getName());
}
arg.name = name;
arguments.add(arg);
realArgumentsCount++;
} catch (Exception e) {
e.printStackTrace();
}
} else { // Const
arguments.add(new ArgumentConst(a));
}
if (pos == -1) {
break;
}
}
if (params.length != realArgumentsCount + 1) {
throw new RuntimeException("Argument count mis-match for " + method.getName());
}
def.arguments = new CommandArgument[arguments.size()];
arguments.toArray(def.arguments);
}
static {
register(new CommandHandler() {
@CommandString("rpgitem help $terms:s[]")
@CommandDocumentation("$command.rpgitem.help")
@CommandGroup("help")
public void help(CommandSender sender, String query) {
searchHelp(sender, query);
}
});
}
public static void searchHelp(CommandSender sender, String terms) {
if (terms.equalsIgnoreCase("_genhelp")) {
for (String locale : Locale.getLocales()) {
generateHelp(locale);
}
return;
}
String locale = sender instanceof Player ? Locale.getPlayerLocale((Player) sender) : "en_GB";
sender.sendMessage(ChatColor.GREEN + String.format(Locale.get("message.help.for", locale), terms));
String[] term = terms.toLowerCase().split(" ");
for (Entry<String, ArrayList<CommandDef>> command : commands.entrySet()) {
for (CommandDef c : command.getValue()) {
int count = 0;
for (String t : term) {
if (c.commandString.toLowerCase().contains(t)) {
count++;
}
}
if (count == term.length) {
StringBuilder buf = new StringBuilder();
buf.append(ChatColor.GREEN).append(ChatColor.BOLD).append('/').append(command.getKey());
for (CommandArgument a : c.arguments) {
buf.append(' ');
if (a.name.length() != 0) {
buf.append(ChatColor.RED).append(ChatColor.BOLD);
buf.append(Locale.get("command.info." + a.name, locale));
}
buf.append(a.isConst() ? ChatColor.GREEN : ChatColor.GOLD).append(ChatColor.BOLD);
buf.append(a.printable(locale));
}
sender.sendMessage(buf.toString());
String docStr = c.documentation;
if (docStr.charAt(0) == '$') {
if (docStr.contains("+")) {
String[] dArgs = docStr.split("\\+");
docStr = Locale.get(dArgs[0].substring(1), locale);
if (dArgs[1].equalsIgnoreCase("PotionEffectType")) {
StringBuilder out = new StringBuilder();
for (PotionEffectType type : PotionEffectType.values()) {
if (type != null)
out.append(type.getName().toLowerCase()).append(", ");
}
docStr += out.toString();
}
} else {
docStr = Locale.get(docStr.substring(1), locale);
}
}
docStr = docStr.replaceAll("@", "" + ChatColor.BLUE).replaceAll("#", "" + ChatColor.WHITE);
StringBuilder docBuf = new StringBuilder();
char[] chars = docStr.toCharArray();
docBuf.append(ChatColor.WHITE);
for (int i = 0; i < chars.length; i++) {
char l = chars[i];
if (l == '&') {
i++;
l = chars[i];
switch (l) {
case '0':
docBuf.append(ChatColor.BLACK);
break;
case '1':
docBuf.append(ChatColor.DARK_BLUE);
break;
case '2':
docBuf.append(ChatColor.DARK_GREEN);
break;
case '3':
docBuf.append(ChatColor.DARK_AQUA);
break;
case '4':
docBuf.append(ChatColor.DARK_RED);
break;
case '5':
docBuf.append(ChatColor.DARK_PURPLE);
break;
case '6':
docBuf.append(ChatColor.GOLD);
break;
case '7':
docBuf.append(ChatColor.GRAY);
break;
case '8':
docBuf.append(ChatColor.DARK_GRAY);
break;
case '9':
docBuf.append(ChatColor.BLUE);
break;
case 'a':
docBuf.append(ChatColor.GREEN);
break;
case 'b':
docBuf.append(ChatColor.AQUA);
break;
case 'c':
docBuf.append(ChatColor.RED);
break;
case 'd':
docBuf.append(ChatColor.LIGHT_PURPLE);
break;
case 'e':
docBuf.append(ChatColor.YELLOW);
break;
case 'f':
docBuf.append(ChatColor.WHITE);
break;
case 'r':
docBuf.append(ChatColor.WHITE);
break;
}
} else {
docBuf.append(l);
}
}
sender.sendMessage(docBuf.toString());
}
}
}
}
private static HashMap<String, String> getMap() {
HashMap<String, String> langMap = new HashMap<String, String>();
langMap.put("en_US", "English (US)");
BufferedReader r = null;
try {
r = new BufferedReader(new InputStreamReader(Plugin.plugin.getResource("languages.txt"), "UTF-8"));
String line = null;
while ((line = r.readLine()) != null) {
String []args = line.split("=");
langMap.put(args[0], args[1]);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
r.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return langMap;
}
public static void generateHelp(String locale) {
BufferedWriter w = null;
HashMap<String, String> langMap = getMap();
try {
File out = new File(Plugin.plugin.getDataFolder(), Calendar.getInstance().get(Calendar.YEAR) + "-" + Calendar.getInstance().get(Calendar.MONTH) + "-" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + locale + ".md");
if (out.exists()) {
out.delete();
}
w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out), "UTF-8"));
w.write("---\n");
w.write("layout: locale\n");
w.write("title: " + langMap.get(locale) + "\n");
w.write("permalink: " + locale + ".html\n");
w.write("---\n");
for (Entry<String, ArrayList<CommandDef>> command : commands.entrySet()) {
w.write(String.format("## Commands /%s ", command.getKey()));
w.write("\n\n");
for (CommandDef c : command.getValue()) {
StringBuilder buf = new StringBuilder();
buf.append("### /");
buf.append(command.getKey()).append(" ");
for (CommandArgument a : c.arguments) {
if (a.name.length() != 0) {
buf.append("<span style='color:#006EFF'>");
buf.append(Locale.get("command.info." + a.name, locale));
buf.append("</span>");
}
if (a.isConst())
buf.append("<span style='color:#b5e853'>");
else
buf.append("<span style='color:#1BE0BF'>");
buf.append(a.printable(locale));
buf.append("</span> ");
}
buf.append("\n");
String docStr = c.documentation;
if (docStr.charAt(0) == '$') {
if (docStr.contains("+")) {
String[] dArgs = docStr.split("\\+");
docStr = Locale.get(dArgs[0].substring(1), locale);
if (dArgs[1].equalsIgnoreCase("PotionEffectType")) {
StringBuilder out2 = new StringBuilder();
for (PotionEffectType type : PotionEffectType.values()) {
if (type != null)
out2.append(type.getName().toLowerCase()).append(", ");
}
docStr += out2.toString();
}
} else {
docStr = Locale.get(docStr.substring(1), locale);
}
}
docStr = docStr.replaceAll("#", "</span>").replaceAll("@", "<span style='color:#0000ff'>").replaceAll("`", "`` ` ``");
StringBuilder docBuf = new StringBuilder();
char[] chars = docStr.toCharArray();
for (int i = 0; i < chars.length; i++) {
char l = chars[i];
if (l == '&') {
i++;
l = chars[i];
if (l != 'r') {
docBuf.append("<span style='color:#");
}
switch (l) {
case '0':
docBuf.append("000000");
break;
case '1':
docBuf.append("0000aa");
break;
case '2':
docBuf.append("00aa00");
break;
case '3':
docBuf.append("00aaaa");
break;
case '4':
docBuf.append("aa0000");
break;
case '5':
docBuf.append("aa00aa");
break;
case '6':
docBuf.append("ffaa00");
break;
case '7':
docBuf.append("aaaaaa");
break;
case '8':
docBuf.append("555555");
break;
case '9':
docBuf.append("5555ff");
break;
case 'a':
docBuf.append("55ff55");
break;
case 'b':
docBuf.append("55ffff");
break;
case 'c':
docBuf.append("ff5555");
break;
case 'd':
docBuf.append("ff55ff");
break;
case 'e':
docBuf.append("ffff55");
break;
case 'f':
docBuf.append("ffffff");
break;
case 'r':
docBuf.append("'></span'");
break;
}
docBuf.append("'>");
} else {
docBuf.append(l);
}
}
buf.append(docBuf.toString());
buf.append("\n\n");
w.write(buf.toString());
}
}
w.write("\n\n");
w.write("Generated at: ");
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
sdf.applyPattern("dd MMM yyyy HH:mm:ss z");
w.write(sdf.format(new Date()));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommandDef implements Comparable<CommandDef> {
public boolean handlePermissions;
public String commandString;
public CommandHandler handler;
public Method method;
public CommandArgument[] arguments;
public String documentation;
public String sortKey;
@Override
public int compareTo(CommandDef o) {
return sortKey.compareToIgnoreCase(o.sortKey);
}
}
abstract class CommandArgument {
public abstract void init(String a);
public abstract Object parse(String in, String locale);
public abstract List<String> tabComplete(String in);
public abstract String printable(String locale);
public abstract Class<?> getType();
public String name = "";
public boolean isConst() {
return false;
}
}
class CommandError {
public String error;
public CommandError(String error) {
this.error = error;
}
}
class ArgumentInteger extends CommandArgument {
private boolean hasLimits;
private int min;
private int max;
@Override
public void init(String a) {
if (a.length() == 0) {
hasLimits = false;
} else {
hasLimits = true;
String[] args = a.split(",");
if (args.length != 2) {
throw new RuntimeException("ArgumentInteger limits errror");
}
min = Integer.parseInt(args[0]);
max = Integer.parseInt(args[1]);
}
}
@Override
public Object parse(String in, String locale) {
if (hasLimits) {
try {
int i = Integer.parseInt(in);
if (i < min || i > max) {
return new CommandError(String.format(Locale.get("message.error.integer.limit", locale), min, max));
}
return i;
} catch (NumberFormatException e) {
return new CommandError(String.format(Locale.get("message.error.integer.format", locale), in));
}
} else {
try {
int i = Integer.parseInt(in);
return i;
} catch (NumberFormatException e) {
return new CommandError(String.format(Locale.get("message.error.integer.format", locale), in));
}
}
}
@Override
public List<String> tabComplete(String in) {
return new ArrayList<String>();
}
@Override
public String printable(String locale) {
if (hasLimits) {
return String.format(Locale.get("command.info.integer.limit", locale), min, max);
}
return Locale.get("command.info.integer", locale);
}
@Override
public Class<?> getType() {
return int.class;
}
}
class ArgumentDouble extends CommandArgument {
private boolean hasLimits;
private double min;
private double max;
@Override
public void init(String a) {
if (a.length() == 0) {
hasLimits = false;
} else {
hasLimits = true;
String[] args = a.split(",");
if (args.length != 2) {
throw new RuntimeException("ArgumentDouble limits errror");
}
min = Double.parseDouble(args[0]);
max = Double.parseDouble(args[1]);
}
}
@Override
public Object parse(String in, String locale) {
if (hasLimits) {
try {
double i = Double.parseDouble(in);
if (i < min || i > max) {
return new CommandError(String.format(Locale.get("message.error.double.limit", locale), min, max));
}
return i;
} catch (NumberFormatException e) {
return new CommandError(String.format(Locale.get("message.error.double.format", locale), in));
}
} else {
try {
double i = Double.parseDouble(in);
return i;
} catch (NumberFormatException e) {
return new CommandError(String.format(Locale.get("message.error.double.format", locale), in));
}
}
}
@Override
public List<String> tabComplete(String in) {
return new ArrayList<String>();
}
@Override
public String printable(String locale) {
if (hasLimits) {
return String.format(Locale.get("command.info.double.limit", locale), min, max);
}
return Locale.get("command.info.double", locale);
}
@Override
public Class<?> getType() {
return double.class;
}
}
class ArgumentString extends CommandArgument {
private int maxLength;
@Override
public void init(String a) {
if (a.length() == 0) {
maxLength = 0;
} else {
maxLength = Integer.parseInt(a);
}
}
@Override
public Object parse(String in, String locale) {
if (maxLength != 0 && in.length() > maxLength)
return new CommandError(String.format(Locale.get("message.error.string.length", locale), in, maxLength));
return in;
}
@Override
public List<String> tabComplete(String in) {
return new ArrayList<String>();
}
@Override
public String printable(String locale) {
if (maxLength != 0)
return String.format(Locale.get("command.info.string.limit", locale), maxLength);
return Locale.get("command.info.string", locale);
}
@Override
public Class<?> getType() {
return String.class;
}
}
class ArgumentConst extends CommandArgument {
public String value;
public ArgumentConst(String v) {
value = v;
}
@Override
public void init(String a) {
throw new RuntimeException("Const cannot be init'ed");
}
@Override
public Object parse(String in, String locale) {
return null;
}
@Override
public List<String> tabComplete(String in) {
ArrayList<String> a = new ArrayList<String>();
String lValue = value;
if (lValue.startsWith(in))
a.add(lValue);
return a;
}
@Override
public String printable(String locale) {
return value;
}
@Override
public boolean isConst() {
return true;
}
@Override
public Class<?> getType() {
return null;
}
}
class ArgumentPlayer extends CommandArgument {
@Override
public void init(String a) {
}
@Override
public Object parse(String in, String locale) {
Player player = Bukkit.getPlayer(in);
if (player == null)
return new CommandError(String.format(Locale.get("message.error.player", locale), in));
return player;
}
@Override
public List<String> tabComplete(String in) {
List<Player> players = Bukkit.matchPlayer(in);
ArrayList<String> out = new ArrayList<String>();
for (Player player : players) {
out.add(player.getName());
}
return out;
}
@Override
public String printable(String locale) {
return Locale.get("command.info.player", locale);
}
@Override
public Class<?> getType() {
return Player.class;
}
}
class ArgumentOption extends CommandArgument {
private String[] options;
private String shortVersion = "";
@Override
public void init(String a) {
if (a.contains("@")) {
String[] args = a.split("@");
shortVersion = args[0];
a = args[1];
}
options = a.split(",");
for (int i = 0; i < options.length; i++) {
options[i] = options[i].trim();
}
}
@Override
public Object parse(String in, String locale) {
for (String o : options) {
if (o.equalsIgnoreCase(in)) {
return o;
}
}
return new CommandError(String.format(Locale.get("message.error.option", locale), in));
}
@Override
public List<String> tabComplete(String in) {
ArrayList<String> out = new ArrayList<String>();
in = in.toLowerCase();
for (String o : options) {
if (o.startsWith(in)) {
out.add(o);
}
}
return out;
}
@Override
public String printable(String locale) {
if (shortVersion.length() == 0) {
StringBuilder out = new StringBuilder();
out.append('[');
for (int i = 0; i < options.length; i++) {
out.append(options[i]).append(i == options.length - 1 ? ']' : ',');
}
return out.toString();
} else {
return "[" + shortVersion + "]";
}
}
@Override
public Class<?> getType() {
return String.class;
}
}
class ArgumentItem extends CommandArgument {
@Override
public void init(String a) {
}
@Override
public Object parse(String in, String locale) {
in = in.toLowerCase();
RPGItem item = ItemManager.getItemByName(in);
if (item == null) {
return new CommandError(String.format(Locale.get("message.error.item", locale), in));
}
return item;
}
@Override
public List<String> tabComplete(String in) {
in = in.toLowerCase();
ArrayList<String> out = new ArrayList<String>();
for (String i : ItemManager.itemByName.keySet()) {
if (i.startsWith(in)) {
out.add(i);
}
}
return out;
}
@Override
public String printable(String locale) {
return Locale.get("command.info.item", locale);
}
@Override
public Class<?> getType() {
return RPGItem.class;
}
}
class ArgumentMaterial extends CommandArgument {
@Override
public void init(String a) {
}
@Override
public Object parse(String in, String locale) {
Material mat = Material.matchMaterial(in);
if (mat == null) {
return new CommandError(String.format(Locale.get("message.error.material", locale), in));
}
return mat;
}
@Override
public List<String> tabComplete(String in) {
ArrayList<String> out = new ArrayList<String>();
String it = in.toUpperCase();
for (Material m : Material.values()) {
if (m.toString().startsWith(it)) {
out.add(m.toString());
}
}
return out;
}
@Override
public String printable(String locale) {
return Locale.get("command.info.material", locale);
}
@Override
public Class<?> getType() {
return Material.class;
}
}
class ArgumentEnum extends CommandArgument {
private Class<?> e;
private List<?> enumConsts;
@Override
public void init(String a) {
try {
e = Class.forName(a);
if (!e.isEnum()) {
throw new RuntimeException(a + " is not an enum");
}
enumConsts = Arrays.asList(e.getEnumConstants());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object parse(String in, String locale) {
Enum<?> en = null;
try {
en = Enum.valueOf((Class<Enum>)e, in.toUpperCase());
} catch (IllegalArgumentException ex) {
return new CommandError(String.format("%s is not a %s", in, e.getSimpleName()));
}
return en;
}
@Override
public List<String> tabComplete(String in) {
ArrayList<String> out = new ArrayList<String>();
String it = in.toUpperCase();
for (Object en : enumConsts) {
if (en.toString().startsWith(it)) {
out.add(en.toString());
}
}
return out;
}
@Override
public String printable(String locale) {
return "[" + e.getSimpleName() + "]";
}
@Override
public Class<?> getType() {
return e;
}
}