mirror of
https://github.com/aikar/commands.git
synced 2026-05-31 06:11:55 +00:00
Initial Project Stuff
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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> {}
|
||||
Reference in New Issue
Block a user