mirror of
https://github.com/TotalFreedomMC/TF-PlotSquared.git
synced 2024-05-19 03:21:25 +00:00
280ced7904
Reason: " How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found."
630 lines
23 KiB
Java
630 lines
23 KiB
Java
/*
|
|
* _____ _ _ _____ _
|
|
* | __ \| | | | / ____| | |
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
* | |
|
|
* |_|
|
|
* PlotSquared plot management system for Minecraft
|
|
* Copyright (C) 2020 IntellectualSites
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.github.intellectualsites.plotsquared.commands;
|
|
|
|
import com.github.intellectualsites.plotsquared.configuration.file.YamlConfiguration;
|
|
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
|
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
|
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
|
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
|
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
|
import com.github.intellectualsites.plotsquared.plot.object.PlotMessage;
|
|
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
|
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
|
|
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
|
|
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
|
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
|
|
import com.github.intellectualsites.plotsquared.plot.util.Permissions;
|
|
import com.github.intellectualsites.plotsquared.plot.util.StringComparison;
|
|
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
public abstract class Command {
|
|
|
|
// May be none
|
|
private final ArrayList<Command> allCommands = new ArrayList<>();
|
|
private final ArrayList<Command> dynamicCommands = new ArrayList<>();
|
|
private final HashMap<String, Command> staticCommands = new HashMap<>();
|
|
|
|
// Parent command (may be null)
|
|
private final Command parent;
|
|
private final boolean isStatic;
|
|
// The command ID
|
|
private String id;
|
|
private List<String> aliases;
|
|
private RequiredType required;
|
|
private String usage;
|
|
private String description;
|
|
private String permission;
|
|
private boolean confirmation;
|
|
private CommandCategory category;
|
|
private Argument[] arguments;
|
|
|
|
public Command(Command parent, boolean isStatic, String id, String permission,
|
|
RequiredType required, CommandCategory category) {
|
|
this.parent = parent;
|
|
this.isStatic = isStatic;
|
|
this.id = id;
|
|
this.permission = permission;
|
|
this.required = required;
|
|
this.category = category;
|
|
this.aliases = Arrays.asList(id);
|
|
if (this.parent != null) {
|
|
this.parent.register(this);
|
|
}
|
|
}
|
|
|
|
public Command(Command parent, boolean isStatic) {
|
|
this.parent = parent;
|
|
this.isStatic = isStatic;
|
|
CommandDeclaration cdAnnotation = getClass().getAnnotation(CommandDeclaration.class);
|
|
if (cdAnnotation != null) {
|
|
init(cdAnnotation);
|
|
}
|
|
for (final Method method : getClass().getDeclaredMethods()) {
|
|
if (method.isAnnotationPresent(CommandDeclaration.class)) {
|
|
Class<?>[] types = method.getParameterTypes();
|
|
// final PlotPlayer player, String[] args, RunnableVal3<Command,Runnable,Runnable> confirm, RunnableVal2<Command, CommandResult>
|
|
// whenDone
|
|
if (types.length == 5 && types[0] == Command.class && types[1] == PlotPlayer.class
|
|
&& types[2] == String[].class && types[3] == RunnableVal3.class
|
|
&& types[4] == RunnableVal2.class) {
|
|
Command tmp = new Command(this, true) {
|
|
@Override
|
|
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args,
|
|
RunnableVal3<Command, Runnable, Runnable> confirm,
|
|
RunnableVal2<Command, CommandResult> whenDone) {
|
|
try {
|
|
method.invoke(Command.this, this, player, args, confirm, whenDone);
|
|
return CompletableFuture.completedFuture(true);
|
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
};
|
|
tmp.init(method.getAnnotation(CommandDeclaration.class));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Command getParent() {
|
|
return this.parent;
|
|
}
|
|
|
|
public String getId() {
|
|
return this.id;
|
|
}
|
|
|
|
public String getFullId() {
|
|
if (this.parent != null && this.parent.getParent() != null) {
|
|
return this.parent.getFullId() + "." + this.id;
|
|
}
|
|
return this.id;
|
|
}
|
|
|
|
public List<Command> getCommands(PlotPlayer player) {
|
|
List<Command> commands = new ArrayList<>();
|
|
for (Command cmd : this.allCommands) {
|
|
if (cmd.canExecute(player, false)) {
|
|
commands.add(cmd);
|
|
}
|
|
}
|
|
return commands;
|
|
}
|
|
|
|
public List<Command> getCommands(CommandCategory category, PlotPlayer player) {
|
|
List<Command> commands = getCommands(player);
|
|
if (category != null) {
|
|
commands.removeIf(command -> command.category != category);
|
|
}
|
|
return commands;
|
|
}
|
|
|
|
public List<Command> getCommands() {
|
|
return this.allCommands;
|
|
}
|
|
|
|
public boolean hasConfirmation(CommandCaller player) {
|
|
return this.confirmation && !player.hasPermission(getPermission() + ".confirm.bypass");
|
|
}
|
|
|
|
public List<String> getAliases() {
|
|
return this.aliases;
|
|
}
|
|
|
|
public String getDescription() {
|
|
return this.description;
|
|
}
|
|
|
|
public RequiredType getRequiredType() {
|
|
return this.required;
|
|
}
|
|
|
|
public Argument[] getRequiredArguments() {
|
|
return this.arguments;
|
|
}
|
|
|
|
public void setRequiredArguments(Argument[] arguments) {
|
|
this.arguments = arguments;
|
|
}
|
|
|
|
public void init(CommandDeclaration declaration) {
|
|
this.id = declaration.command();
|
|
this.permission = declaration.permission();
|
|
this.required = declaration.requiredType();
|
|
this.category = declaration.category();
|
|
List<String> aliasOptions = new ArrayList<>();
|
|
aliasOptions.add(this.id);
|
|
aliasOptions.addAll(Arrays.asList(declaration.aliases()));
|
|
HashMap<String, Object> options = new HashMap<>();
|
|
options.put("aliases", aliasOptions);
|
|
options.put("description", declaration.description());
|
|
options.put("usage", declaration.usage());
|
|
options.put("confirmation", declaration.confirmation());
|
|
boolean set = false;
|
|
YamlConfiguration commands =
|
|
PlotSquared.get() == null ? new YamlConfiguration() : PlotSquared.get().commands;
|
|
for (Map.Entry<String, Object> entry : options.entrySet()) {
|
|
String key = this.getFullId() + "." + entry.getKey();
|
|
if (!commands.contains(key)) {
|
|
commands.set(key, entry.getValue());
|
|
set = true;
|
|
}
|
|
}
|
|
if (set && PlotSquared.get() != null) {
|
|
try {
|
|
commands.save(PlotSquared.get().commandsFile);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
|
|
}
|
|
}
|
|
this.aliases = commands.getStringList(this.getFullId() + ".aliases");
|
|
this.description = commands.getString(this.getFullId() + ".description");
|
|
this.usage = commands.getString(this.getFullId() + ".usage");
|
|
this.confirmation = commands.getBoolean(this.getFullId() + ".confirmation");
|
|
if (this.parent != null) {
|
|
this.parent.register(this);
|
|
}
|
|
}
|
|
|
|
public void register(Command command) {
|
|
if (command.isStatic) {
|
|
for (String alias : command.aliases) {
|
|
this.staticCommands.put(alias.toLowerCase(), command);
|
|
}
|
|
} else {
|
|
this.dynamicCommands.add(command);
|
|
}
|
|
this.allCommands.add(command);
|
|
}
|
|
|
|
public String getPermission() {
|
|
if (this.permission != null && !this.permission.isEmpty()) {
|
|
return this.permission;
|
|
}
|
|
if (this.parent == null) {
|
|
return "plots.use";
|
|
}
|
|
return "plots." + getFullId();
|
|
}
|
|
|
|
public <T> void paginate(PlotPlayer player, List<T> c, int size, int page,
|
|
RunnableVal3<Integer, T, PlotMessage> add, String baseCommand, String header) {
|
|
// Calculate pages & index
|
|
if (page < 0) {
|
|
page = 0;
|
|
}
|
|
int totalPages = (int) Math.ceil(c.size() / size);
|
|
if (page > totalPages) {
|
|
page = totalPages;
|
|
}
|
|
int max = page * size + size;
|
|
if (max > c.size()) {
|
|
max = c.size();
|
|
}
|
|
// Send the header
|
|
header = header.replaceAll("%cur", page + 1 + "").replaceAll("%max", totalPages + 1 + "")
|
|
.replaceAll("%amount%", c.size() + "").replaceAll("%word%", "all");
|
|
MainUtil.sendMessage(player, header);
|
|
// Send the page content
|
|
List<T> subList = c.subList(page * size, max);
|
|
int i = page * size;
|
|
for (T obj : subList) {
|
|
i++;
|
|
PlotMessage msg = new PlotMessage();
|
|
add.run(i, obj, msg);
|
|
msg.send(player);
|
|
}
|
|
// Send the footer
|
|
if (page < totalPages && page > 0) { // Back | Next
|
|
new PlotMessage().text("<-").color("$1").command(baseCommand + " " + page).text(" | ")
|
|
.color("$3").text("->").color("$1").command(baseCommand + " " + (page + 2))
|
|
.text(Captions.CLICKABLE.getTranslated()).color("$2").send(player);
|
|
return;
|
|
}
|
|
if (page == 0 && totalPages != 0) { // Next
|
|
new PlotMessage().text("<-").color("$3").text(" | ").color("$3").text("->").color("$1")
|
|
.command(baseCommand + " " + 2).text(Captions.CLICKABLE.getTranslated()).color("$2")
|
|
.send(player);
|
|
return;
|
|
}
|
|
if (totalPages != 0) { // Back
|
|
new PlotMessage().text("<-").color("$1").command(baseCommand + " " + page).text(" | ")
|
|
.color("$3").text("->").color("$3").text(Captions.CLICKABLE.getTranslated())
|
|
.color("$2").send(player);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param player Caller
|
|
* @param args Arguments
|
|
* @param confirm Instance, Success, Failure
|
|
* @return CompletableFuture true if the command executed fully, false in
|
|
* any other case
|
|
*/
|
|
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args,
|
|
RunnableVal3<Command, Runnable, Runnable> confirm,
|
|
RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
|
|
if (args.length == 0 || args[0] == null) {
|
|
if (this.parent == null) {
|
|
MainCommand.getInstance().help.displayHelp(player, null, 0);
|
|
} else {
|
|
Captions.COMMAND_SYNTAX.send(player, getUsage());
|
|
}
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
if (this.allCommands.isEmpty()) {
|
|
player.sendMessage(
|
|
"Not Implemented: https://github.com/IntellectualSites/PlotSquared/issues/new");
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
Command cmd = getCommand(args[0]);
|
|
if (cmd == null) {
|
|
if (this.parent != null) {
|
|
Captions.COMMAND_SYNTAX.send(player, getUsage());
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
// Help command
|
|
try {
|
|
if (!MathMan.isInteger(args[0])) {
|
|
CommandCategory.valueOf(args[0].toUpperCase());
|
|
}
|
|
// This will default certain syntax to the help command
|
|
// e.g. /plot, /plot 1, /plot claiming
|
|
MainCommand.getInstance().help.execute(player, args, null, null);
|
|
return CompletableFuture.completedFuture(false);
|
|
} catch (IllegalArgumentException ignored) {
|
|
}
|
|
// Command recommendation
|
|
MainUtil.sendMessage(player, Captions.NOT_VALID_SUBCOMMAND);
|
|
List<Command> commands = getCommands(player);
|
|
if (commands.isEmpty()) {
|
|
MainUtil.sendMessage(player, Captions.DID_YOU_MEAN,
|
|
MainCommand.getInstance().help.getUsage());
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
HashSet<String> setArgs = new HashSet<>(args.length);
|
|
for (String arg : args) {
|
|
setArgs.add(arg.toLowerCase());
|
|
}
|
|
String[] allArgs = setArgs.toArray(new String[0]);
|
|
int best = 0;
|
|
for (Command current : commands) {
|
|
int match = getMatch(allArgs, current);
|
|
if (match > best) {
|
|
cmd = current;
|
|
}
|
|
}
|
|
if (cmd == null) {
|
|
cmd = new StringComparison<>(args[0], this.allCommands).getMatchObject();
|
|
}
|
|
MainUtil.sendMessage(player, Captions.DID_YOU_MEAN, cmd.getUsage());
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
|
|
if (!cmd.checkArgs(player, newArgs) || !cmd.canExecute(player, true)) {
|
|
return CompletableFuture.completedFuture(false);
|
|
}
|
|
try {
|
|
cmd.execute(player, newArgs, confirm, whenDone);
|
|
} catch (CommandException e) {
|
|
e.perform(player);
|
|
}
|
|
return CompletableFuture.completedFuture(true);
|
|
}
|
|
|
|
public boolean checkArgs(PlotPlayer player, String[] args) {
|
|
Argument<?>[] reqArgs = getRequiredArguments();
|
|
if (reqArgs != null && reqArgs.length > 0) {
|
|
boolean failed = args.length < reqArgs.length;
|
|
String[] baseSplit = getCommandString().split(" ");
|
|
String[] fullSplit = getUsage().split(" ");
|
|
String base = getCommandString();
|
|
if (fullSplit.length - baseSplit.length < reqArgs.length) {
|
|
String[] tmp = new String[baseSplit.length + reqArgs.length];
|
|
System.arraycopy(fullSplit, 0, tmp, 0, fullSplit.length);
|
|
fullSplit = tmp;
|
|
}
|
|
for (int i = 0; i < reqArgs.length; i++) {
|
|
fullSplit[i + baseSplit.length] = reqArgs[i].getExample().toString();
|
|
failed = failed || reqArgs[i].parse(args[i]) == null;
|
|
}
|
|
if (failed) {
|
|
Captions.COMMAND_SYNTAX.send(player, StringMan.join(fullSplit, " "));
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public int getMatch(String[] args, Command cmd) {
|
|
String perm = cmd.getPermission();
|
|
HashSet<String> desc = new HashSet<>();
|
|
int count = cmd.getAliases().stream().filter(alias -> alias.startsWith(args[0]))
|
|
.mapToInt(alias -> 5).sum();
|
|
Collections.addAll(desc, cmd.getDescription().split(" "));
|
|
for (String arg : args) {
|
|
if (perm.startsWith(arg)) {
|
|
count++;
|
|
}
|
|
if (desc.contains(arg)) {
|
|
count++;
|
|
}
|
|
}
|
|
String[] usage = cmd.getUsage().split(" ");
|
|
for (int i = 0; i < Math.min(4, usage.length); i++) {
|
|
int require;
|
|
if (usage[i].startsWith("<")) {
|
|
require = 1;
|
|
} else {
|
|
require = 0;
|
|
}
|
|
String[] split = usage[i].split("\\|| |\\>|\\<|\\[|\\]|\\{|\\}|\\_|\\/");
|
|
for (String aSplit : split) {
|
|
for (String arg : args) {
|
|
if (arg.equalsIgnoreCase(aSplit)) {
|
|
count += 5 - i + require;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
count += StringMan.intersection(desc, args);
|
|
return count;
|
|
}
|
|
|
|
public Command getCommand(String arg) {
|
|
Command cmd = this.staticCommands.get(arg.toLowerCase());
|
|
if (cmd == null) {
|
|
for (Command command : this.dynamicCommands) {
|
|
if (command.matches(arg)) {
|
|
return command;
|
|
}
|
|
}
|
|
}
|
|
return cmd;
|
|
}
|
|
|
|
public Command getCommand(Class clazz) {
|
|
for (Command cmd : this.allCommands) {
|
|
if (cmd.getClass() == clazz) {
|
|
return cmd;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Command getCommandById(String id) {
|
|
Command exact = this.staticCommands.get(id);
|
|
if (exact != null) {
|
|
return exact;
|
|
}
|
|
for (Command cmd : this.allCommands) {
|
|
if (cmd.getId().equals(id)) {
|
|
return cmd;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public boolean canExecute(PlotPlayer player, boolean message) {
|
|
if (player == null) {
|
|
return true;
|
|
}
|
|
if (!this.required.allows(player)) {
|
|
if (message) {
|
|
MainUtil.sendMessage(player, this.required == RequiredType.PLAYER ?
|
|
Captions.IS_CONSOLE :
|
|
Captions.NOT_CONSOLE);
|
|
}
|
|
} else if (!Permissions.hasPermission(player, getPermission())) {
|
|
if (message) {
|
|
Captions.NO_PERMISSION.send(player, getPermission());
|
|
}
|
|
} else {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean matches(String arg) {
|
|
arg = arg.toLowerCase();
|
|
return StringMan.isEqual(arg, this.id) || this.aliases.contains(arg);
|
|
}
|
|
|
|
public String getCommandString() {
|
|
if (this.parent == null) {
|
|
return "/" + toString();
|
|
} else {
|
|
return this.parent.getCommandString() + " " + toString();
|
|
}
|
|
}
|
|
|
|
public String getUsage() {
|
|
if (this.usage != null && !this.usage.isEmpty()) {
|
|
if (this.usage.startsWith("/")) {
|
|
return this.usage;
|
|
}
|
|
return getCommandString() + " " + this.usage;
|
|
}
|
|
if (this.allCommands.isEmpty()) {
|
|
return getCommandString();
|
|
}
|
|
StringBuilder args = new StringBuilder("[");
|
|
String prefix = "";
|
|
for (Command cmd : this.allCommands) {
|
|
args.append(prefix).append(cmd.isStatic ? cmd.toString() : "<" + cmd + ">");
|
|
prefix = "|";
|
|
}
|
|
return getCommandString() + " " + args + "]";
|
|
}
|
|
|
|
public Collection<Command> tabOf(PlotPlayer player, String[] input, boolean space,
|
|
String... args) {
|
|
if (!space) {
|
|
return null;
|
|
}
|
|
List<Command> result = new ArrayList<>();
|
|
int index = input.length;
|
|
for (String arg : args) {
|
|
arg = arg.replace(getCommandString() + " ", "");
|
|
String[] split = arg.split(" ");
|
|
if (split.length <= index) {
|
|
continue;
|
|
}
|
|
arg = StringMan.join(Arrays.copyOfRange(split, index, split.length), " ");
|
|
Command cmd = new Command(null, false, arg, getPermission(), getRequiredType(), null) {
|
|
};
|
|
result.add(cmd);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
|
|
switch (args.length) {
|
|
case 0:
|
|
return this.allCommands;
|
|
case 1:
|
|
String arg = args[0].toLowerCase();
|
|
if (space) {
|
|
Command cmd = getCommand(arg);
|
|
if (cmd != null && cmd.canExecute(player, false)) {
|
|
return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space);
|
|
} else {
|
|
return null;
|
|
}
|
|
} else {
|
|
Set<Command> commands = new HashSet<Command>();
|
|
for (Map.Entry<String, Command> entry : this.staticCommands.entrySet()) {
|
|
if (entry.getKey().startsWith(arg) && entry.getValue()
|
|
.canExecute(player, false)) {
|
|
commands.add(entry.getValue());
|
|
}
|
|
}
|
|
return commands;
|
|
}
|
|
default:
|
|
Command cmd = getCommand(args[0]);
|
|
if (cmd != null) {
|
|
return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override public String toString() {
|
|
return !this.aliases.isEmpty() ? this.aliases.get(0) : this.id;
|
|
}
|
|
|
|
@Override public boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (getClass() != obj.getClass()) {
|
|
return false;
|
|
}
|
|
Command other = (Command) obj;
|
|
if (this.hashCode() != other.hashCode()) {
|
|
return false;
|
|
}
|
|
return this.getFullId().equals(other.getFullId());
|
|
}
|
|
|
|
@Override public int hashCode() {
|
|
return this.getFullId().hashCode();
|
|
}
|
|
|
|
public void checkTrue(boolean mustBeTrue, Captions message, Object... args) {
|
|
if (!mustBeTrue) {
|
|
throw new CommandException(message, args);
|
|
}
|
|
}
|
|
|
|
public <T extends Object> T check(T object, Captions message, Object... args) {
|
|
if (object == null) {
|
|
throw new CommandException(message, args);
|
|
}
|
|
return object;
|
|
}
|
|
|
|
public enum CommandResult {
|
|
FAILURE, SUCCESS
|
|
}
|
|
|
|
|
|
public static class CommandException extends RuntimeException {
|
|
private final Object[] args;
|
|
private final Captions message;
|
|
|
|
public CommandException(Captions message, Object... args) {
|
|
this.message = message;
|
|
this.args = args;
|
|
}
|
|
|
|
public void perform(PlotPlayer player) {
|
|
if (player != null && message != null) {
|
|
message.send(player, args);
|
|
}
|
|
}
|
|
}
|
|
}
|