Initial Project Stuff

This commit is contained in:
Aikar
2016-12-21 19:25:11 -05:00
parent a03cf7eff5
commit ec749bf578
28 changed files with 2532 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>co.aikar</groupId>
<artifactId>command</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>aikar</id>
<url>http://ci.emc.gs/nexus/content/groups/aikar/</url>
</repository>
<repository>
<id>paper</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
</repositories>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.10-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,466 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Subcommand;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.SetMultimap;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.util.StringUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public abstract class BaseCommand extends Command {
private final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create();
protected String execLabel;
protected String execSubcommand;
protected String[] origArgs;
public BaseCommand() {
this(null);
}
public BaseCommand(String cmd) {
super(cmd);
final Class<? extends BaseCommand> self = this.getClass();
CommandAlias rootCmdAlias = self.getAnnotation(CommandAlias.class);
if (cmd == null) {
if (rootCmdAlias == null) {
cmd = "__" + self.getSimpleName();
} else {
cmd = Patterns.PIPE.split(rootCmdAlias.value())[0];
}
cmd = cmd.toLowerCase();
setName(cmd);
setLabel(cmd);
}
this.description = cmd + " commands";
this.usageMessage = "/" + cmd;
final CommandPermission perm = self.getAnnotation(CommandPermission.class);
if (perm != null) {
this.setPermission(perm.value());
}
boolean foundDefault = false;
for (Method method : self.getDeclaredMethods()) {
method.setAccessible(true);
String sublist = null;
final Subcommand sub = method.getAnnotation(Subcommand.class);
final Default def = method.getAnnotation(Default.class);
final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class);
if (def != null) {
if (!foundDefault) {
registerSubcommand(method, "__default");
foundDefault = true;
} else {
SneakyThrow.sneaky(new InvalidConfigurationException("Multiple @Default commands"));
}
}
if (sub != null) {
sublist = sub.value();
} else if (commandAliases != null) {
sublist = commandAliases.value();
}
if (sublist != null) {
registerSubcommand(method, sublist);
}
}
try {
Method unknown = self.getMethod("onUnknown", CommandSender.class, String.class, String[].class);
unknown.setAccessible(true);
registerSubcommand(unknown, "__unknown");
} catch (NoSuchMethodException ignored) {}
if (rootCmdAlias != null) {
List<String> cmdList = new ArrayList<>();
Collections.addAll(cmdList, Patterns.PIPE.split(rootCmdAlias.value().toLowerCase()));
cmdList.remove(cmd);
for (String cmdAlias : cmdList) {
register(cmdAlias, new ForwardingCommand(this));
}
}
register(getName(), this);
}
private boolean register(String name, Command cmd) {
return Bukkit.getServer().getCommandMap().register(name.toLowerCase(), "empire", cmd);
}
private void registerSubcommand(Method method, String subCommand) {
subCommand = subCommand.toLowerCase();
final String[] subCommandParts = Patterns.SPACE.split(subCommand);
// Must run getSubcommandPossibility BEFORE we rewrite it just after this.
List<String> cmdList = getSubCommandPossibilityList(subCommandParts);
// Strip pipes off for auto complete addition
for (int i = 0; i < subCommandParts.length; i++) {
subCommandParts[i] = Patterns.PIPE.split(subCommandParts[i])[0];
}
String prefSubCommand = StringUtils.join(subCommandParts, " ");
final CommandAlias cmdAlias = method.getAnnotation(CommandAlias.class);
final String[] aliasNames = cmdAlias != null ? Patterns.PIPE.split(cmdAlias.value().toLowerCase()) : null;
String cmdName = aliasNames != null ? aliasNames[0] : getLabel() + " ";
RegisteredCommand cmd = new RegisteredCommand(this, cmdName, method, prefSubCommand);
for (String subcmd : cmdList) {
subCommands.put(subcmd, cmd);
}
if (aliasNames != null) {
for (String name : aliasNames) {
register(name, new ForwardingCommand(this, subCommandParts));
}
}
}
/**
* Takes a string like "foo|bar baz|qux" and generates a list of
* - foo baz
* - foo qux
* - bar baz
* - bar qux
*
* For every possible sub command combination
*
* @param subCommandParts
* @return List of all sub command possibilities
*/
private static List<String> getSubCommandPossibilityList(String[] subCommandParts) {
int i = 0;
ArrayList<String> current = null;
while (true) {
ArrayList<String> newList = new ArrayList<>();
if (i < subCommandParts.length) {
for (String s1 : Patterns.PIPE.split(subCommandParts[i])) {
if (current != null) {
newList.addAll(current.stream().map(s -> s + " " + s1).collect(Collectors.toList()));
} else {
newList.add(s1);
}
}
}
if (i + 1 < subCommandParts.length) {
current = newList;
i = i + 1;
continue;
}
return newList;
}
}
@Override
public final boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) {
return true;
}
commandLabel = commandLabel.toLowerCase();
if (preCommand(sender, commandLabel, args)) {
return true;
}
execSubcommand = null;
execLabel = commandLabel;
origArgs = args;
if (args.length == 0) {
onDefault(sender, commandLabel);
return true;
}
CommandSearch cmd = findSubCommand(args);
if (cmd != null) {
execSubcommand = cmd.getCheckSub();
final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length);
executeCommand(sender, execargs, cmd.cmd);
return true;
}
if (!onUnknown(sender, commandLabel, args)) {
help(sender, args);
}
return true;
}
private CommandSearch findSubCommand(String[] args) {
return findSubCommand(args, false);
}
private CommandSearch findSubCommand(String[] args, boolean completion) {
for (int i = args.length; i >= 0; i--) {
String checkSub = StringUtils.join(args, " ", 0, i).toLowerCase();
Set<RegisteredCommand> cmds = subCommands.get(checkSub);
final int extraArgs = args.length - i;
if (!cmds.isEmpty()) {
RegisteredCommand cmd = null;
if (cmds.size() == 1) {
cmd = Iterables.getOnlyElement(cmds);
} else {
Optional<RegisteredCommand> optCmd = cmds.stream().filter(c -> {
int nonSender = c.nonSenderAwareResolvers;
int partialSender = c.optionalResolvers;
return extraArgs <= nonSender + partialSender && (completion || extraArgs >= nonSender);
}).sorted((c1, c2) -> {
int a = c1.nonSenderAwareResolvers + c1.optionalResolvers;
int b = c2.nonSenderAwareResolvers + c2.optionalResolvers;
if (a == b) {
return 0;
}
return a < b ? 1 : -1;
}).findFirst();
if (optCmd.isPresent()) {
cmd = optCmd.get();
}
}
if (cmd != null) {
return new CommandSearch(cmd, i, checkSub);
}
}
}
return null;
}
private static void executeCommand(CommandSender sender, String[] args, RegisteredCommand cmd) {
if (cmd.hasPermission(sender)) {
List<String> sargs = Lists.newArrayList(args);
cmd.invoke(sender, sargs);
} else {
CommandUtil.sendMsg(sender, "&cI'm sorry, but you do not have permission to perform this command.");
}
}
public boolean canExecute(CommandSender sender, RegisteredCommand cmd) {
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String commandLabel, String[] args)
throws IllegalArgumentException {
commandLabel = commandLabel.toLowerCase();
final CommandSearch search = findSubCommand(args, true);
if (search != null) {
args = Arrays.copyOfRange(args, search.argIndex, args.length);
return completeCommand(sender, search.cmd, args, commandLabel);
}
String argString = StringUtils.join(args, " ").toLowerCase();
final List<String> cmds = new ArrayList<>();
for (Map.Entry<String, RegisteredCommand> entry : subCommands.entries()) {
final String key = entry.getKey();
if (key.startsWith(argString) && !"__unknown".equals(key)) {
final RegisteredCommand value = entry.getValue();
if (!value.hasPermission(sender)) {
continue;
}
String prefCommand = value.prefSubCommand;
final String[] psplit = Patterns.SPACE.split(prefCommand);
cmds.add(psplit[args.length - 1]);
}
}
final Set<RegisteredCommand> unknownCmds = subCommands.get("__unknown");
if (cmds.isEmpty() && !unknownCmds.isEmpty()) {
RegisteredCommand unknownCommand = null;
if (unknownCmds.size() == 1) {
unknownCommand = Iterables.getOnlyElement(unknownCmds);
}
if (unknownCommand != null) {
return completeCommand(sender, unknownCommand, args, commandLabel);
}
}
return filterTabComplete(args[args.length-1], cmds);
}
private List<String> completeCommand(CommandSender sender, RegisteredCommand cmd, String[] args, String commandLabel) {
if (args.length > cmd.nonSenderAwareResolvers + cmd.optionalResolvers) {
return ImmutableList.of();
}
if (args.length == 0 || cmd.complete == null) {
return args.length < 2 ? super.tabComplete(sender, commandLabel, args) : ImmutableList.of();
}
String[] completions = Patterns.SPACE.split(cmd.complete.value());
final int argIndex = args.length - 1;
String input = args[argIndex];
final String completion = argIndex < completions.length ? completions[argIndex] : null;
if ("@players".equals(completion)) {
return super.tabComplete(sender, commandLabel, args);
}
List<String> cmds = CommandCompletions.of(sender, completion, input);
if (cmds.isEmpty()) {
cmds = ImmutableList.of(input);
}
return filterTabComplete(args[(argIndex)], cmds);
}
private static List<String> filterTabComplete(String arg, List<String> cmds) {
return cmds.stream()
.distinct()
.filter(cmd -> cmd != null && (arg.isEmpty() || StringUtil.startsWithIgnoreCase(cmd, arg)))
.collect(Collectors.toList());
}
public void help(CommandSender sender, String[] args) {
CommandUtil.sendMsg(sender, "&cUnknown Command, please type &f/help");
}
public void onDefault(CommandSender sender, String commandLabel) {
executeDefault(sender);
}
public boolean onUnknown(CommandSender sender, String commandLabel, String[] args) {
help(sender, args);
return true;
}
public boolean executeDefault(CommandSender sender, String... args) {
final Set<RegisteredCommand> defs = subCommands.get("__default");
RegisteredCommand def = null;
if (!defs.isEmpty()) {
if (defs.size() == 1) {
def = Iterables.getOnlyElement(defs);
}
if (def != null) {
executeCommand(sender, args, def);
return true;
}
}
return false;
}
public boolean preCommand(CommandSender sender, String commandLabel, String[] args) {
return false;
}
public void doHelp(CommandSender sender, String... args) {
help(sender, args);
}
public void showSyntax(CommandSender sender, RegisteredCommand cmd) {
CommandUtil.sendMsg(sender, "&cUsage: /" + cmd.command + " " + cmd.syntax);
}
/*@Data*/ /*@AllArgsConstructor*/
private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub;
public CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) {
this.cmd = cmd;
this.argIndex = argIndex;
this.checkSub = checkSub;
}
public RegisteredCommand getCmd() {
return this.cmd;
}
public int getArgIndex() {
return this.argIndex;
}
public String getCheckSub() {
return this.checkSub;
}
public void setCmd(RegisteredCommand cmd) {
this.cmd = cmd;
}
public void setArgIndex(int argIndex) {
this.argIndex = argIndex;
}
public void setCheckSub(String checkSub) {
this.checkSub = checkSub;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof CommandSearch)) {
return false;
}
final CommandSearch other = (CommandSearch) o;
if (!other.canEqual(this)) {
return false;
}
final Object this$cmd = this.getCmd();
final Object other$cmd = other.getCmd();
if (this$cmd == null ? other$cmd != null : !this$cmd.equals(other$cmd)) {
return false;
}
if (this.getArgIndex() != other.getArgIndex()) {
return false;
}
final Object this$checkSub = this.getCheckSub();
final Object other$checkSub = other.getCheckSub();
if (this$checkSub == null ? other$checkSub != null : !this$checkSub.equals(other$checkSub)) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $cmd = this.getCmd();
result = result * PRIME + ($cmd == null ? 43 : $cmd.hashCode());
result = result * PRIME + this.getArgIndex();
final Object $checkSub = this.getCheckSub();
result = result * PRIME + ($checkSub == null ? 43 : $checkSub.hashCode());
return result;
}
protected boolean canEqual(Object other) {
return other instanceof CommandSearch;
}
public String toString() {
return "com.empireminecraft.commands.EmpireCommand.CommandSearch(cmd=" + this.getCmd() + ", argIndex=" + this.getArgIndex() + ", checkSub=" +
this.getCheckSub() + ")";
}
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public final class CommandCompletions {
private CommandCompletions() {}
private static final List<String> EMPTY = ImmutableList.of();
public static List<String> of(CommandSender sender, String completion, String input) {
if (completion == null) {
return ImmutableList.of();
}
String[] complete = Patterns.COLON.split(completion, 2);
switch (complete[0]) {
case "@range":
if (complete.length == 1) {
return ImmutableList.of();
}
final String[] ranges = Patterns.DASH.split(complete[1]);
int start;
int end;
if (ranges.length != 2) {
start = 0;
end = CommandUtil.parseInt(ranges[0], 0);
} else {
start = CommandUtil.parseInt(ranges[0], 0);
end = CommandUtil.parseInt(ranges[1], 0);
}
return IntStream.rangeClosed(start, end).mapToObj(Integer::toString).collect(Collectors.toList());
case "@timeunits":
return ImmutableList.of("hours", "days", "weeks", "months", "minutes");
case "@mobs":
final Stream<String> normal = Stream.of(EntityType.values())
.map(entityType -> CommandUtil.simplifyString(entityType.getName()));
return normal.collect(Collectors.toList());
default:
return Lists.newArrayList(Patterns.PIPE.split(completion));
}
}
}
@@ -0,0 +1,684 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@SuppressWarnings("WeakerAccess")
public final class CommandUtil {
public static final Random RANDOM = new Random();
private CommandUtil() {}
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
public static String padLeft(String s, int n) {
return String.format("%1$" + n + "s", s);
}
public static String formatNumber(Integer balance) {
return NumberFormat.getInstance().format(balance);
}
public static String formatLocation(Location loc) {
if (loc == null) {
return null;
}
return loc.getWorld().getName() +
":" +
loc.getBlockX() +
"," +
loc.getBlockY() +
"," +
loc.getBlockZ();
}
public static String color(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
public static void sendMsg(CommandSender player, String message) {
message = color(message);
if (player == null) {
for (String msg : Patterns.NEWLINE.split(message)) {
Log.info(msg);
}
} else {
for (String msg : Patterns.NEWLINE.split(message)) {
player.sendMessage(msg);
}
}
}
public static Location stringToLocation(String storedLoc) {
return stringToLocation(storedLoc, null);
}
public static Location stringToLocation(String storedLoc, World forcedWorld) {
if (storedLoc == null) {
return null;
}
String[] args = Patterns.COLON.split(storedLoc);
if (args.length >= 4 || (args.length == 3 && forcedWorld != null)) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
int i = args.length == 3 ? 0 : 1;
double x = Double.parseDouble(args[i]);
double y = Double.parseDouble(args[i + 1]);
double z = Double.parseDouble(args[i + 2]);
Location loc = new Location(Bukkit.getWorld(world), x, y, z);
if (args.length >= 6) {
loc.setPitch(Float.parseFloat(args[4]));
loc.setYaw(Float.parseFloat(args[5]));
}
return loc;
} else if (args.length == 2) {
String[] args2 = Patterns.COMMA.split(args[1]);
if (args2.length == 3) {
String world = forcedWorld != null ? forcedWorld.getName() : args[0];
double x = Double.parseDouble(args2[0]);
double y = Double.parseDouble(args2[1]);
double z = Double.parseDouble(args2[2]);
return new Location(Bukkit.getWorld(world), x, y, z);
}
}
return null;
}
public static String fullLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(NumUtil.precision(loc.getX(), 4))
.append(':')
.append(NumUtil.precision(loc.getY(), 4))
.append(':')
.append(NumUtil.precision(loc.getZ(), 4))
.append(':')
.append(NumUtil.precision(loc.getPitch(), 4))
.append(':')
.append(NumUtil.precision(loc.getYaw(), 4))
.toString();
}
public static String fullBlockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(64))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.append(':')
.append(NumUtil.precision(loc.getPitch(), 4))
.append(':')
.append(NumUtil.precision(loc.getYaw(), 4))
.toString();
}
public static String blockLocationToString(Location loc) {
if (loc == null) {
return null;
}
return (new StringBuilder(32))
.append(loc.getWorld().getName())
.append(':')
.append(loc.getBlockX())
.append(':')
.append(loc.getBlockY())
.append(':')
.append(loc.getBlockZ())
.toString();
}
public static <T extends Enum> T getEnumFromName(T[] types, String name) {
return getEnumFromName(types, name, null);
}
public static <T extends Enum> T getEnumFromName(T[] types, String name, T def) {
for (T type : types) {
if (type.name().equalsIgnoreCase(name)) {
return type;
}
}
return def;
}
public static <T extends Enum> T getEnumFromOrdinal(T[] types, int ordinal) {
for (T type : types) {
if (type.ordinal() == ordinal) {
return type;
}
}
return null;
}
public static String ucfirst(String str) {
return WordUtils.capitalizeFully(str);
}
public static Double parseDouble(String var) {
return parseDouble(var, null);
}
public static Double parseDouble(String var, Double def) {
if (var == null) {
return def;
}
try {
return Double.parseDouble(var);
} catch (NumberFormatException ignored) {}
return def;
}
public static Float parseFloat(String var) {
return parseFloat(var, null);
}
public static Float parseFloat(String var, Float def) {
if (var == null) {
return def;
}
try {
return Float.parseFloat(var);
} catch (NumberFormatException ignored) {}
return def;
}
public static Long parseLong(String var) {
return parseLong(var, null);
}
public static Long parseLong(String var, Long def) {
if (var == null) {
return def;
}
try {
return Long.parseLong(var);
} catch (NumberFormatException ignored) {}
return def;
}
public static Integer parseInt(String var) {
return parseInt(var, null);
}
public static Integer parseInt(String var, Integer def) {
if (var == null) {
return def;
}
try {
return Integer.parseInt(var);
} catch (NumberFormatException ignored) {}
return def;
}
public static boolean randBool() {
return RANDOM.nextBoolean();
}
public static <T> T nullDefault(Object val, Object def) {
return (T) (val != null ? val : def);
}
public static String join(Collection<String> args) {
return StringUtils.join(args, " ");
}
public static String join(Collection<String> args, String sep) {
return StringUtils.join(args, sep);
}
public static String join(String[] args) {
return join(args, 0, ' ');
}
public static String join(String[] args, String sep) {
return StringUtils.join(args, sep);
}
public static String join(String[] args, char sep) {
return join(args, 0, sep);
}
public static String join(String[] args, int index) {
return join(args, index, ' ');
}
public static String join(String[] args, int index, char sep) {
return StringUtils.join(args, sep, index, args.length);
}
public static String simplifyString(String str) {
if (str == null) {
return null;
}
return Patterns.NON_ALPHA_NUMERIC.matcher(str.toLowerCase()).replaceAll("");
}
public static double round(double x, int scale) {
try {
return (new BigDecimal
(Double.toString(x))
.setScale(scale, BigDecimal.ROUND_HALF_UP))
.doubleValue();
} catch (NumberFormatException ex) {
if (Double.isInfinite(x)) {
return x;
} else {
return Double.NaN;
}
}
}
public static int roundUp(int num, int multiple) {
if(multiple == 0) {
return num;
}
int remainder = num % multiple;
if (remainder == 0) {
return num;
}
return num + multiple - remainder;
}
public static String removeColors(String msg) {
return ChatColor.stripColor(CommandUtil.color(msg));
}
public static String replaceChatString(String message, String replace, String with) {
return replaceChatString(message, Pattern.compile(Pattern.quote(replace), Pattern.CASE_INSENSITIVE), with);
}
public static String replaceChatString(String message, Pattern replace, String with) {
final String[] split = replace.split(message + "1");
if (split.length < 2) {
return replace.matcher(message).replaceAll(with);
}
message = split[0];
for (int i = 1; i < split.length; i++) {
final String prev = ChatColor.getLastColors(message);
message += with + prev + split[i];
}
return message.substring(0, message.length() - 1);
}
public static boolean isWithinDistance(@NotNull Player p1, @NotNull Player p2, int dist) {
return isWithinDistance(p1.getLocation(), p2.getLocation(), dist);
}
public static boolean isWithinDistance(@NotNull Location loc1, @NotNull Location loc2, int dist) {
return loc1.getWorld() == loc2.getWorld() && loc1.distance(loc2) <= dist;
}
public static String limit(String str, int limit) {
return str.length() > limit ? str.substring(0, limit) : str;
}
/**
* Plain string replacement, escapes replace value.
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replace(String string, Pattern pattern, String repl) {
return pattern.matcher(string).replaceAll(Matcher.quoteReplacement(repl));
}
/**
* Regex version of {@link #replace(String, Pattern, String)}
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replacePattern(String string, Pattern pattern, String repl) {
return pattern.matcher(string).replaceAll(repl);
}
/**
* Plain String replacement. If you need regex patterns, see {@link #replacePattern(String, String, String)}
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replace(String string, String pattern, String repl) {
return replace(string, Patterns.getPattern(Pattern.quote(pattern)), repl);
}
/**
* Regex version of {@link #replace(String, String, String)}
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replacePattern(String string, String pattern, String repl) {
return replace(string, Patterns.getPattern(pattern), repl);
}
/**
* Pure Regex Pattern matching and replacement, no escaping
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replacePatternMatch(String string, Pattern pattern, String repl) {
return pattern.matcher(string).replaceAll(repl);
}
/**
* Pure Regex Pattern matching and replacement, no escaping
* @param string
* @param pattern
* @param repl
* @return
*/
public static String replacePatternMatch(String string, String pattern, String repl) {
return replacePatternMatch(string, Patterns.getPattern(pattern), repl);
}
public static String replaceStrings(String string, String... replacements) {
if (replacements.length < 2 || replacements.length % 2 != 0) {
throw new IllegalArgumentException("Invalid Replacements");
}
for (int i = 0; i < replacements.length; i += 2) {
String key = replacements[i];
String value = replacements[i+1];
if (value == null) value = "";
string = replace(string, key, value);
}
return string;
}
public static String replacePatterns(String string, String... replacements) {
if (replacements.length < 2 || replacements.length % 2 != 0) {
throw new IllegalArgumentException("Invalid Replacements");
}
for (int i = 0; i < replacements.length; i += 2) {
String key = replacements[i];
String value = replacements[i+1];
if (value == null) value = "";
string = replacePattern(string, key, value);
}
return string;
}
/**
* Copied from Apache Commons WordUtils, with an exception to skip spaces after delimiters.
*
* @see org.apache.commons.lang.WordUtils#capitalize(String, char[])
* @param str
* @param delimiters
* @return
*/
public static String capitalize(String str, char[] delimiters) {
int delimLen = (delimiters == null ? -1 : delimiters.length);
if (str == null || str.isEmpty() || delimLen == 0) {
return str;
}
int strLen = str.length();
StringBuilder builder = new StringBuilder(strLen);
boolean capitalizeNext = true;
for (int i = 0; i < strLen; i++) {
char ch = str.charAt(i);
if (isDelimiter(ch, delimiters)) {
builder.append(ch);
capitalizeNext = true;
} else if (ch != ' ' && capitalizeNext) {
builder.append(Character.toTitleCase(ch));
capitalizeNext = false;
} else {
builder.append(ch);
}
}
return builder.toString();
}
private static boolean isDelimiter(char ch, char[] delimiters) {
if (delimiters == null) {
return Character.isWhitespace(ch);
}
for (char delimiter : delimiters) {
if (ch == delimiter) {
return true;
}
}
return false;
}
public static <T> T random(List<T> arr) {
if (arr == null || arr.isEmpty()) {
return null;
}
return arr.get(RANDOM.nextInt(arr.size()));
}
public static <T> T random(T[] arr) {
if (arr == null || arr.length == 0) {
return null;
}
return arr[RANDOM.nextInt(arr.length)];
}
/**
* Added as im sure we will try to "Find this" again. This is no different than Enum.values() passed to above method logically
* but the array version is slightly faster.
* @param enm
* @param <T>
* @return
*/
@Deprecated
public static <T extends Enum<?>> T random(Class<? extends T> enm) {
return random(enm.getEnumConstants());
}
public static String normalize(String s) {
if (s == null) {
return null;
}
return Patterns.NON_PRINTABLE_CHARACTERS.matcher(Normalizer.normalize(s, Form.NFD)).replaceAll("");
}
public static int indexOf(String arg, String[] split) {
for (int i = 0; i < split.length; i++) {
if (arg == null) {
if (split[i] == null) {
return i;
}
} else if (arg.equals(split[i])) {
return i;
}
}
return -1;
}
public static String capitalizeFirst(String name) {
return capitalizeFirst(name, '_');
}
public static String capitalizeFirst(String name, char separator) {
name = name.toLowerCase();
String[] split = name.split(Character.toString(separator));
StringBuilder total = new StringBuilder(3);
for (String s : split) {
total.append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).append(' ');
}
return total.toString().trim();
}
public static List<String> enumNames(Enum<?>[] values) {
return Stream.of(values).map(Enum::name).collect(Collectors.toList());
}
public static List<String> enumNames(Class<? extends Enum<?>> cls) {
return enumNames(cls.getEnumConstants());
}
public static String combine(String[] args) {
return combine(args, 0);
}
public static String combine(String[] args, int start) {
int size = 0;
for (int i = start; i < args.length; i++) {
size += args[i].length();
}
StringBuilder sb = new StringBuilder(size);
for (int i = start; i < args.length; i++) {
sb.append(args[i]);
}
return sb.toString();
}
public static double distance(@NotNull Entity e1, @NotNull Entity e2) {
return distance(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Entity e1, @NotNull Entity e2) {
return distance2d(e1.getLocation(), e2.getLocation());
}
public static double distance2d(@NotNull Location loc1, @NotNull Location loc2) {
loc1 = loc1.clone();
loc1.setY(loc2.getY());
return distance(loc1, loc2);
}
public static double distance(@NotNull Location loc1, @NotNull Location loc2) {
if (loc1.getWorld() != loc2.getWorld()) {
return 0;
}
return loc1.distance(loc2);
}
public static Location getTargetLoc(Player player) {
return getTargetLoc(player, 128);
}
public static Location getTargetLoc(Player player, int maxDist) {
return getTargetLoc(player, maxDist, 1.5);
}
public static Location getTargetLoc(Player player, int maxDist, double addY) {
try {
Location target = player.getTargetBlock((Set<Material>) null, maxDist).getLocation();
target.setY(target.getY() + addY);
return target;
} catch (Exception ignored) {
return null;
}
}
public static Location getRandLoc(Location loc, int radius) {
return getRandLoc(loc, radius, radius, radius);
}
public static Location getRandLoc(Location loc, int xzRadius, int yRadius) {
return getRandLoc(loc, xzRadius, yRadius, xzRadius);
}
@NotNull public static Location getRandLoc(Location loc, int xRadius, int yRadius, int zRadius) {
Location newLoc = loc.clone();
newLoc.setX(NumUtil.rand(loc.getX()-xRadius, loc.getX()+xRadius));
newLoc.setY(NumUtil.rand(loc.getY()-yRadius, loc.getY()+yRadius));
newLoc.setZ(NumUtil.rand(loc.getZ()-zRadius, loc.getZ()+zRadius));
return newLoc;
}
@Nullable public static Enum<?> simpleMatch(Class<? extends Enum<?>> list, String item) {
if (item == null) {
return null;
}
item = CommandUtil.simplifyString(item);
for (Enum<?> s : list.getEnumConstants()) {
String simple = CommandUtil.simplifyString(s.name());
if (item.equals(simple)) {
return s;
}
}
return null;
}
@NotNull public static Boolean isTruthy(String test) {
switch (test) {
case "t":
case "true":
case "on":
case "y":
case "yes":
case "1":
return true;
}
return false;
}
public static Number parseNumber(String num, boolean suffixes) {
double mod = 1;
if (suffixes) {
switch (num.charAt(num.length()-1)) {
case 'M':
case 'm':
mod = 1000000D;
num = num.substring(0, num.length()-1);
break;
case 'K':
case 'k':
mod = 1000D;
num = num.substring(0, num.length()-1);
}
}
return Double.parseDouble(num) * mod;
}
public static <T> boolean hasIntersection(Collection<T> list1, Collection<T> list2) {
for (T t : list1) {
if (list2.contains(t)) {
return true;
}
}
return false;
}
public static <T> Collection<T> intersection(Collection<T> list1, Collection<T> list2) {
List<T> list = new ArrayList<>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
public class ForwardingCommand extends Command {
private final Command command;
private final String[] baseArgs;
private static final String[] NO_ARGS = new String[0];
public ForwardingCommand(Command command) {
this(command, NO_ARGS);
}
public ForwardingCommand(Command command, String[] baseArgs) {
super(command.getName());
this.command = command;
this.baseArgs = baseArgs;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
return command.tabComplete(sender, alias, (String[]) ArrayUtils.addAll(baseArgs, args));
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
return command.execute(sender, commandLabel, (String[]) ArrayUtils.addAll(baseArgs, args));
}
}
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
public class InvalidCommandArgument extends Exception {
public boolean showSyntax = true;
public InvalidCommandArgument() {
this(null);
}
public InvalidCommandArgument(boolean showSyntax) {
this(null, showSyntax);
}
public InvalidCommandArgument(String message) {
this(message, true);
}
public InvalidCommandArgument(String message, boolean showSyntax) {
super(message, null, false, false);
this.showSyntax = showSyntax;
}
}
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import org.apache.commons.lang.exception.ExceptionUtils;
import java.util.logging.Logger;
public final class Log {
public static Logger LOGGER;
private Log() {}
public static void log(String message) {
info(message);
}
public static void info(String message) {
for (String s : Patterns.NEWLINE.split(message)) {
LOGGER.info(s);
}
}
public static void warn(String message) {
for (String s : Patterns.NEWLINE.split(message)) {
LOGGER.warning(s);
}
}
public static void severe(String message) {
for (String s : Patterns.NEWLINE.split(message)) {
LOGGER.severe(s);
}
}
public static void error(String message) {
severe(message);
}
public static void exception(String msg) {
exception(new Throwable(msg));
}
public static void exception(Throwable e) {
exception(e.getMessage(), e);
}
public static void exception(String msg, Throwable e) {
if (msg != null) {
severe(msg);
}
severe(ExceptionUtils.getFullStackTrace(e));
}
public static void exception(Throwable dbg, int lines) {
if (dbg == null) {
return;
}
severe(dbg.getMessage());
final StackTraceElement current = new Throwable().getStackTrace()[1];
severe("c: "+ current.getClassName()+":" + current.getLineNumber());
final StackTraceElement[] stack = dbg.getStackTrace();
for (int i = 0; i < lines && i < stack.length; i++) {
final StackTraceElement cur = stack[i];
Logger.getGlobal().severe(" " + cur);
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import org.apache.commons.lang.StringUtils;
public final class NumUtil {
private NumUtil() {}
public static int rand(int min, int max) {
return min + CommandUtil.RANDOM.nextInt(max - min + 1);
}
/**
* Calculate random between 2 points, excluding a center
* ex: Util.rand(-12, -6, 6, 12) would not return -5 to 5
* @param min1
* @param max1
* @param min2
* @param max2
* @return
*/
public static int rand(int min1, int max1, int min2, int max2) {
return CommandUtil.randBool() ? rand(min1, max1) : rand(min2, max2);
}
public static double rand(double min, double max) {
return CommandUtil.RANDOM.nextDouble() * (max - min) + min;
}
public static boolean isNumber(String str) {
return StringUtils.isNumeric(str);
}
public static String intToRoman(int integer) {
if (integer == 1) {
return "I";
}
if (integer == 2) {
return "II";
}
if (integer == 3) {
return "III";
}
if (integer == 4) {
return "IV";
}
if (integer == 5) {
return "V";
}
if (integer == 6) {
return "VI";
}
if (integer == 7) {
return "VII";
}
if (integer == 8) {
return "VIII";
}
if (integer == 9) {
return "IX";
}
if (integer == 10) {
return "X";
}
return null;
}
public static boolean isInteger(String string) {
if (!Patterns.INTEGER.matcher(string).matches()) {
return false;
}
return true;
}
public static boolean isFloat(String string) {
try {
Float.parseFloat(string);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isDouble(String string) {
try {
Double.parseDouble(string);
return true;
} catch (Exception e) {
return false;
}
}
public static boolean isBetween(float num, double min, double max) {
if (num >= min && num <= max){
return true;
} else {
return false;
}
}
public static double precision(double x, int p) {
double pow = Math.pow(10, p);
return Math.round(x * pow) / pow;
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
@SuppressWarnings("WeakerAccess")
public final class Patterns {
public static final Pattern COMMA = Pattern.compile(",");
public static final Pattern NEWLINE = Pattern.compile("\n");
public static final Pattern DASH = Pattern.compile("-");
public static final Pattern SPACE = Pattern.compile(" ");
public static final Pattern SEMICOLON = Pattern.compile(";");
public static final Pattern COLON = Pattern.compile(":");
public static final Pattern PIPE = Pattern.compile("\\|");
public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[^a-zA-Z0-9]");
public static final Pattern INTEGER = Pattern.compile("^[0-9]+$");
public static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]{2,16}$");
public static final Pattern NON_PRINTABLE_CHARACTERS = Pattern.compile("[^\\x20-\\x7F]");
public static final Pattern EQUALS = Pattern.compile("=");
private Patterns() {}
@SuppressWarnings("Convert2MethodRef")
static final LoadingCache<String, Pattern> patternCache =
CacheBuilder.newBuilder()
.expireAfterAccess(90, TimeUnit.DAYS)
.maximumSize(1024)
// has to be this or fails to compile
.build(CacheLoader.from((pattern) -> Pattern.compile(pattern)));
public static Pattern getPattern(String pattern) {
try {
return patternCache.get(pattern);
} catch (ExecutionException e) {
e.printStackTrace();
return Pattern.compile(pattern);
}
}
}
@@ -0,0 +1,181 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Syntax;
import co.aikar.commands.annotation.Values;
import co.aikar.commands.contexts.CommandContexts;
import co.aikar.commands.contexts.CommandExecutionContext;
import co.aikar.commands.contexts.ContextResolver;
import co.aikar.commands.contexts.SenderAwareContextResolver;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class RegisteredCommand {
public final BaseCommand scope;
public final String command;
public final Method method;
public final String prefSubCommand;
public final Parameter[] parameters;
public final ContextResolver<?>[] resolvers;
public final String syntax;
public final CommandPermission perm;
public final CommandCompletion complete;
public final int nonSenderAwareResolvers;
public final int optionalResolvers;
RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) {
this.scope = scope;
if ("__unknown".equals(prefSubCommand)) {
prefSubCommand = "";
}
this.command = command + (method.getAnnotation(CommandAlias.class) == null && !prefSubCommand.isEmpty() ? prefSubCommand : "");
this.method = method;
this.prefSubCommand = prefSubCommand;
this.perm = method.getAnnotation(CommandPermission.class);
this.complete = method.getAnnotation(CommandCompletion.class);
this.parameters = method.getParameters();
this.resolvers = new ContextResolver[this.parameters.length];
final Syntax syntaxStr = method.getAnnotation(Syntax.class);
int nonSenderAwareResolvers = 0;
int optionalResolvers = 0;
StringBuilder syntaxB = new StringBuilder(64);
for (int i = 0; i < parameters.length; i++) {
final Parameter parameter = parameters[i];
final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = CommandContexts.getResolver(type);
if (resolver != null) {
resolvers[i] = resolver;
if (type == World.class || resolver instanceof SenderAwareContextResolver || parameter.getAnnotation(Optional.class) != null
|| parameter.getAnnotation(Default.class) != null) {
optionalResolvers++;
} else {
nonSenderAwareResolvers++;
}
if (!CommandSender.class.isAssignableFrom(parameter.getType())) {
if (parameter.getAnnotation(Default.class) != null ||
parameter.getAnnotation(Optional.class) != null ||
resolver instanceof SenderAwareContextResolver) {
syntaxB.append('[').append(parameter.getName()).append("] ");
} else {
syntaxB.append('<').append(parameter.getName()).append("> ");
}
}
} else {
SneakyThrow.sneaky(new InvalidConfigurationException(
"Parameter " + type.getSimpleName() + " of " + this.command + " has no resolver"
));
}
}
if (syntaxStr != null) {
this.syntax = syntaxStr.value();
} else {
this.syntax = syntaxB.toString();
}
this.nonSenderAwareResolvers = nonSenderAwareResolvers;
this.optionalResolvers = optionalResolvers;
}
public void invoke(CommandSender sender, List<String> args) {
if (!scope.canExecute(sender, this)) {
return;
}
try {
Map<String, Object> passedArgs = Maps.newLinkedHashMap();
for (int i = 0; i < parameters.length; i++) {
boolean isLast = i == parameters.length - 1;
final Parameter parameter = parameters[i];
final String parameterName = parameter.getName();
final Class<?> type = parameter.getType();
final ContextResolver<?> resolver = resolvers[i];
if (resolver != null) {
CommandExecutionContext context = new CommandExecutionContext(this, parameter, sender, args, i, passedArgs);
if (args.isEmpty() && !(isLast && type == String[].class)) {
Default def = parameter.getAnnotation(Default.class);
Optional opt = parameter.getAnnotation(Optional.class);
if (isLast && def != null) {
args.add(def.value());
} else if (isLast && opt != null) {
passedArgs.put(parameterName, resolver instanceof SenderAwareContextResolver ? resolver.getContext(context) : null);
continue;
} else if (!(resolver instanceof SenderAwareContextResolver)) {
scope.showSyntax(sender, this);
return;
}
} else {
final Values values = parameter.getAnnotation(Values.class);
if (values != null) {
String arg = args.get(0);
final String[] split = Patterns.PIPE.split(values.value());
Set<String> possible = Sets.newHashSet();
for (String s : split) {
List<String> check = CommandCompletions.of(sender, s, arg);
if (!check.isEmpty()) {
possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList()));
} else {
possible.add(s.toLowerCase());
}
}
if (!possible.contains(arg.toLowerCase())) {
throw new InvalidCommandArgument("Must be one of: " + CommandUtil.join(possible, ", "));
}
}
}
passedArgs.put(parameterName, resolver.getContext(context));
} else {
CommandUtil.sendMsg(sender, "&cUnexpected Error. Staff have been notified of the bug.");
return;
}
}
method.invoke(scope, passedArgs.values().toArray());
} catch (Exception e) {
if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) {
e = (Exception) e.getCause();
}
if (e instanceof InvalidCommandArgument) {
if (e.getMessage() != null && !e.getMessage().isEmpty()) {
CommandUtil.sendMsg(sender, "&cError: " + e.getMessage());
}
if (((InvalidCommandArgument) e).showSyntax) {
scope.showSyntax(sender, this);
}
} else {
CommandUtil.sendMsg(sender, "&cI'm sorry, but there was an error performing this command.");
Log.exception("Exception in command: " + command + " " + CommandUtil.join(args), e.getCause());
}
}
}
public boolean hasPermission(CommandSender check) {
return perm == null || !(check instanceof Player) || check.hasPermission(perm.value());
}
}
@@ -0,0 +1,16 @@
package co.aikar.commands;
public class SneakyThrow
{
public static void sneaky(Throwable t)
{
throw SneakyThrow.<RuntimeException>superSneaky( t );
}
private static <T extends Throwable> T superSneaky(Throwable t) throws T
{
throw (T) t;
}
}
@@ -0,0 +1,68 @@
package co.aikar.commands;
import com.google.common.collect.Iterables;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class UserUtil {
public static Player findPlayerSmart(CommandSender requester, String origname) {
String name = CommandUtil.replace(origname, ":confirm", "");
if (name.length() < 3) {
requester.sendMessage("§cUsername too short, must be at least three characters");
return null;
}
if (!isValidName(name)) {
requester.sendMessage("§c'" + name + "' is not a valid username");
return null;
}
List<Player> matches = Bukkit.getServer().matchPlayer(name);
List<Player> confirmList = new ArrayList<>();
// Remove confirmList players from smart matching.
Iterator<Player> iter = matches.iterator();
while (iter.hasNext()) {
Player player = iter.next();
if (requester instanceof Player && !((Player) requester).canSee(player)) {
if (requester.hasPermission("command.seevanish")) {
if (!origname.endsWith(":confirm")) {
confirmList.add(player);
iter.remove();
}
} else {
iter.remove();
}
}
}
if (matches.size() > 1 || confirmList.size() > 1) {
requester.sendMessage("§cMultiple players matched '" + name + "', please be more specific");
return null;
}
if (matches.isEmpty()) {
if (confirmList.isEmpty()) {
requester.sendMessage("§cNo player matching '" + name + "' is connected to this server");
return null;
} else {
Player player = Iterables.getOnlyElement(confirmList);
CommandUtil.sendMsg(requester,
"&cWarning: " + player.getDisplayName() + "&c is confirmList. Do not blow their cover!\n" +
"&cTo confirm your action, add &f:confirm&c to the end of their name. \n" +
"&bEx: &e/g " + player.getName() + ":confirm");
return null;
}
}
return matches.get(0);
}
public static boolean isValidName(String name) {
return name != null && !name.isEmpty() && Patterns.VALID_NAME_PATTERN.matcher(name).matches();
}
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandAlias {
String value();
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandCompletion {
String value();
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermission {
String value();
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Default {
String value() default "";
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Flags {
String value();
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Optional {
}
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Don't join remaining arguments
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Single {}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Split {
String value() default ",";
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Subcommand {
String value();
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Syntax {
String value();
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Values {
String value();
}
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.contexts;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Split;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Values;
import co.aikar.commands.Log;
import co.aikar.commands.Patterns;
import co.aikar.commands.SneakyThrow;
import co.aikar.commands.UserUtil;
import co.aikar.commands.CommandUtil;
import com.google.common.collect.Maps;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
public final class CommandContexts {
private static final Map<Class<?>, ContextResolver<?>> contextMap = Maps.newHashMap();
private CommandContexts() {}
public static void initialize() {
registerContext(Integer.class, (c) -> {
try {
return CommandUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes")).intValue();
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Long.class, (c) -> {
try {
return CommandUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes")).longValue();
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Float.class, (c) -> {
try {
return CommandUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes")).floatValue();
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Double.class, (c) -> {
try {
return CommandUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes")).doubleValue();
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Number.class, (c) -> {
try {
return CommandUtil.parseNumber(c.popFirstArg(), c.hasFlag("suffixes"));
} catch (NumberFormatException e) {
throw new InvalidCommandArgument("Must be a number");
}
});
registerContext(Boolean.class, (c) -> CommandUtil.isTruthy(c.popFirstArg()));
registerContext(String.class, (c) -> {
final Values values = c.getParam().getAnnotation(Values.class);
if (values != null) {
return c.popFirstArg();
}
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
return CommandUtil.join(c.getArgs());
}
return c.popFirstArg();
});
registerContext(String[].class, (c) -> {
String val;
if (c.isLastArg() && c.getParam().getAnnotation(Single.class) == null) {
val = CommandUtil.join(c.getArgs());
} else {
val = c.popFirstArg();
}
Split split = c.getParam().getAnnotation(Split.class);
if (split != null) {
if (val.isEmpty()) {
throw new InvalidCommandArgument();
}
return Patterns.getPattern(split.value()).split(val);
} else if (!c.isLastArg()) {
SneakyThrow.sneaky(new InvalidConfigurationException("Weird Command signature... String[] should be last or @Split"));
}
String[] result = c.getArgs().toArray(new String[c.getArgs().size()]);
c.getArgs().clear();
return result;
});
registerContext(OnlinePlayer.class, (c) -> {
final String playercheck = c.popFirstArg();
Player player = UserUtil.findPlayerSmart(c.getSender(), playercheck);
if (player == null) {
CommandUtil.sendMsg(c.getSender(), "&cCould not find a player by the name " + playercheck);
throw new InvalidCommandArgument(false);
}
return new OnlinePlayer(player);
});
registerSenderAwareContext(World.class, (c) -> {
String firstArg = c.getFirstArg();
World world = firstArg != null ? Bukkit.getWorld(firstArg) : null;
if (world != null) {
c.popFirstArg();
}
if (world == null && c.getSender() instanceof Player) {
world = ((Entity) c.getSender()).getWorld();
}
if (world == null) {
throw new InvalidCommandArgument("Invalid World");
}
return world;
});
registerSenderAwareContext(CommandSender.class, CommandExecutionContext::getSender);
registerSenderAwareContext(Player.class, (c) -> {
Player player = c.getSender() instanceof Player ? (Player) c.getSender() : null;
if (player == null && !c.hasAnnotation(Optional.class)) {
throw new InvalidCommandArgument("Requires a player to run this command", false);
}
if (player != null && c.hasFlag("itemheld") && !isValidItem(player.getInventory().getItemInMainHand())) {
throw new InvalidCommandArgument("You must be holding an item in your main hand.", false);
}
return player;
});
registerContext(Enum.class, (c) -> {
final String first = c.popFirstArg();
Class<? extends Enum<?>> enumCls = (Class<? extends Enum<?>>) c.getParam().getType();
Enum<?> match = CommandUtil.simpleMatch(enumCls, first);
if (match == null) {
List<String> names = CommandUtil.enumNames(enumCls);
throw new InvalidCommandArgument("Please specify one of: " + CommandUtil.join(names));
}
return match;
});
}
public static <T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T> supplier) {
contextMap.put(context, supplier);
}
public static <T> void registerContext(Class<T> context, ContextResolver<T> supplier) {
contextMap.put(context, supplier);
}
public static ContextResolver<?> getResolver(Class<?> type) {
Class<?> rootType = type;
do {
if (type == Object.class) {
break;
}
final ContextResolver<?> resolver = contextMap.get(type);
if (resolver != null) {
return resolver;
}
} while ((type = type.getSuperclass()) != null);
Log.exception(new InvalidConfigurationException("No context resolver defined for " + rootType.getName()));
return null;
}
private static boolean isValidItem(ItemStack item) {
return item != null && item.getType() != Material.AIR && item.getAmount() > 0;
}
}
@@ -0,0 +1,238 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.contexts;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.Patterns;
import co.aikar.commands.CommandUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.bukkit.command.CommandSender;
import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
/*@Data*/ public class CommandExecutionContext {
private final RegisteredCommand cmd;
private final Parameter param;
private final CommandSender sender;
private final List<String> args;
private final int index;
private final Map<String, Object> passedArgs;
private final Map<String, String> flags;
public CommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandSender sender, List<String> args,
int index, Map<String, Object> passedArgs) {
this.cmd = cmd;
this.param = param;
this.sender = sender;
this.args = args;
this.index = index;
this.passedArgs = passedArgs;
Flags flags = param.getAnnotation(Flags.class);
if (flags != null) {
this.flags = Maps.newHashMap();
for (String s : Patterns.COMMA.split(flags.value())) {
String[] v = Patterns.EQUALS.split(s, 2);
this.flags.put(v[0], v.length > 1 ? v[1] : null);
}
} else {
this.flags = ImmutableMap.of();
}
}
public String popFirstArg() {
return !args.isEmpty() ? args.remove(0) : null;
}
public String getFirstArg() {
return !args.isEmpty() ? args.get(0) : null;
}
public boolean isLastArg() {
return cmd.parameters.length -1 == index;
}
public int getNumParams() {
return cmd.parameters.length;
}
public boolean canOverridePlayerContext() {
int numRequired = getNumParams();
for (int i = 0; i < cmd.resolvers.length; i++) {
Parameter parameter = cmd.parameters[i];
ContextResolver<?> resolver = cmd.resolvers[i];
if (parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Default.class) != null) {
numRequired--;
} else if (resolver instanceof SenderAwareContextResolver) {
numRequired--;
}
}
return numRequired >= args.size();
}
public Object getResolvedArg(String arg) {
return passedArgs.get(arg);
}
public Object getResolvedArg(Class<?>... classes) {
for (Class<?> clazz : classes) {
for (Object passedArg : passedArgs.values()) {
if (clazz.isInstance(passedArg)) {
return passedArg;
}
}
}
return null;
}
public <T> T getResolvedArg(String key, Class<?>... classes) {
final Object o = passedArgs.get(key);
for (Class<?> clazz : classes) {
if (clazz.isInstance(o)) {
return (T) o;
}
}
return null;
}
public boolean isOptional() {
return param.getAnnotation(Optional.class) != null;
}
public boolean hasFlag(String flag) {
return flags.containsKey(flag);
}
public String getFlagValue(String flag, String def) {
return flags.containsKey(flag) ? flags.get(flag) : def;
}
public Integer getFlagValue(String flag, Integer def) {
return CommandUtil.parseInt(this.flags.get(flag), def);
}
public <T extends Annotation> T getAnnotation(Class<T> cls) {
return param.getAnnotation(cls);
}
public <T extends Annotation> boolean hasAnnotation(Class<T> cls) {
return param.getAnnotation(cls) != null;
}
public RegisteredCommand getCmd() {
return this.cmd;
}
public Parameter getParam() {
return this.param;
}
public CommandSender getSender() {
return this.sender;
}
public List<String> getArgs() {
return this.args;
}
public int getIndex() {
return this.index;
}
public Map<String, Object> getPassedArgs() {
return this.passedArgs;
}
public Map<String, String> getFlags() {
return this.flags;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof CommandExecutionContext)) {
return false;
}
final CommandExecutionContext other = (CommandExecutionContext) o;
if (!other.canEqual(this)) {
return false;
}
final Object this$cmd = this.getCmd();
final Object other$cmd = other.getCmd();
if (this$cmd == null ? other$cmd != null : !this$cmd.equals(other$cmd)) {
return false;
}
final Object this$param = this.getParam();
final Object other$param = other.getParam();
if (this$param == null ? other$param != null : !this$param.equals(other$param)) {
return false;
}
final Object this$sender = this.getSender();
final Object other$sender = other.getSender();
if (this$sender == null ? other$sender != null : !this$sender.equals(other$sender)) {
return false;
}
final Object this$args = this.getArgs();
final Object other$args = other.getArgs();
if (this$args == null ? other$args != null : !this$args.equals(other$args)) {
return false;
}
if (this.getIndex() != other.getIndex()) {
return false;
}
final Object this$passedArgs = this.getPassedArgs();
final Object other$passedArgs = other.getPassedArgs();
if (this$passedArgs == null ? other$passedArgs != null : !this$passedArgs.equals(other$passedArgs)) {
return false;
}
final Object this$flags = this.getFlags();
final Object other$flags = other.getFlags();
if (this$flags == null ? other$flags != null : !this$flags.equals(other$flags)) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $cmd = this.getCmd();
result = result * PRIME + ($cmd == null ? 43 : $cmd.hashCode());
final Object $param = this.getParam();
result = result * PRIME + ($param == null ? 43 : $param.hashCode());
final Object $sender = this.getSender();
result = result * PRIME + ($sender == null ? 43 : $sender.hashCode());
final Object $args = this.getArgs();
result = result * PRIME + ($args == null ? 43 : $args.hashCode());
result = result * PRIME + this.getIndex();
final Object $passedArgs = this.getPassedArgs();
result = result * PRIME + ($passedArgs == null ? 43 : $passedArgs.hashCode());
final Object $flags = this.getFlags();
result = result * PRIME + ($flags == null ? 43 : $flags.hashCode());
return result;
}
protected boolean canEqual(Object other) {
return other instanceof CommandExecutionContext;
}
public String toString() {
return "com.empireminecraft.commands.contexts.CommandExecutionContext(cmd=" + this.getCmd() + ", param=" + this.getParam() + ", sender=" +
this.getSender() + ", args=" + this.getArgs() + ", index=" + this.getIndex() + ", passedArgs=" + this.getPassedArgs() + ", flags=" +
this.getFlags() + ")";
}
}
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.contexts;
import co.aikar.commands.InvalidCommandArgument;
@FunctionalInterface
public interface ContextResolver <C> {
C getContext(CommandExecutionContext c) throws InvalidCommandArgument;
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.contexts;
import org.bukkit.entity.Player;
/*@Data*/ public class OnlinePlayer {
public final Player player;
public OnlinePlayer(Player player) {
this.player = player;
}
public Player getPlayer() {
return this.player;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof OnlinePlayer)) {
return false;
}
final OnlinePlayer other = (OnlinePlayer) o;
if (!other.canEqual(this)) {
return false;
}
final Object this$player = this.getPlayer();
final Object other$player = other.getPlayer();
if (this$player == null ? other$player != null : !this$player.equals(other$player)) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $player = this.getPlayer();
result = result * PRIME + ($player == null ? 43 : $player.hashCode());
return result;
}
protected boolean canEqual(Object other) {
return other instanceof OnlinePlayer;
}
public String toString() {
return "com.empireminecraft.commands.contexts.OnlinePlayer(player=" + this.getPlayer() + ")";
}
}
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2016. Starlis LLC / dba Empire Minecraft
*
* This source code is proprietary software and must not be redistributed without Starlis LLC's approval
*
*/
package co.aikar.commands.contexts;
public interface SenderAwareContextResolver<C> extends ContextResolver <C> {}