ProjectAres/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/commands/CommandUtils.java

222 lines
9.1 KiB
Java

package tc.oc.commons.bukkit.commands;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import tc.oc.api.docs.PlayerId;
import tc.oc.api.docs.Server;
import tc.oc.commons.bukkit.chat.ComponentRenderers;
import tc.oc.commons.bukkit.localization.Translations;
import tc.oc.commons.core.chat.Component;
import tc.oc.commons.core.commands.TranslatableCommandException;
import tc.oc.commons.core.util.TimeUtils;
public abstract class CommandUtils {
public static final String CONSOLE_DISPLAY_NAME = ChatColor.GOLD + "" + ChatColor.AQUA + "Console";
public static final BaseComponent CONSOLE_COMPONENT_NAME = new Component(new Component("").color(net.md_5.bungee.api.ChatColor.GOLD),
new Component("Console").color(net.md_5.bungee.api.ChatColor.AQUA));
public static Optional<String> flag(CommandContext args, char flag) {
return Optional.ofNullable(args.getFlag(flag));
}
public static CommandException newCommandException(CommandSender sender, BaseComponent message) {
return new CommandException(ComponentRenderers.toLegacyText(message, sender));
}
public static Player senderToPlayer(CommandSender sender) throws CommandException {
if(sender instanceof Player) {
return (Player) sender;
} else {
throw new CommandException(ComponentRenderers.toLegacyText(new TranslatableComponent("command.onlyPlayers"), sender));
}
}
/**
* Get an online {@link Player} by exact name
*/
public static Player getPlayer(CommandContext args, CommandSender sender, int index) throws CommandException {
if(args.argsLength() > index) {
Player player = sender.getServer().getPlayerExact(args.getString(index), sender);
if(player == null) throw new CommandException(ComponentRenderers.toLegacyText(new TranslatableComponent("command.playerNotFound"), sender));
return player;
} else {
throw new CommandException(ComponentRenderers.toLegacyText(new TranslatableComponent("command.specifyPlayer"), sender));
}
}
/**
* Get an online {@link Player} by exact name, defaulting to sender
*/
public static Player getPlayerOrSelf(CommandContext args, CommandSender sender, int index) throws CommandException {
return senderToPlayer(getCommandSenderOrSelf(args, sender, index));
}
/**
* Get an online {@link CommandSender} by exact name, defaulting to sender
*/
public static CommandSender getCommandSenderOrSelf(CommandContext args, CommandSender sender, int index) throws CommandException {
if(args.argsLength() > index) {
Player player = sender.getServer().getPlayerExact(args.getString(index), sender);
if(player == null) throw new CommandException(ComponentRenderers.toLegacyText(new TranslatableComponent("command.playerNotFound"), sender));
return player;
} else {
return sender;
}
}
/**
* Get an online {@link Player} by partial name.
* @throws CommandException if the name does not match any player, or matches multiple players
*/
public static Player findOnlinePlayer(CommandContext args, CommandSender sender, int index) throws CommandException {
if(args.argsLength() > index) {
String name = args.getString(index);
List<Player> players = sender.getServer().matchPlayer(name, sender);
switch(players.size()) {
case 0: throw new CommandException(Translations.get().t("command.playerNotFound", sender));
case 1: return players.get(0);
default: throw new CommandException(Translations.get().t("command.multiplePlayersFound", sender));
}
} else {
throw new CommandException(Translations.get().t("command.specifyPlayer", sender));
}
}
public static void assertPermission(Permissible permissible, String permission) throws CommandPermissionsException {
if(!permissible.hasPermission(permission)) {
throw new CommandPermissionsException();
}
}
public static void assertPermission(Permissible permissible, Permission permission) throws CommandPermissionsException {
if(!permissible.hasPermission(permission)) {
throw new CommandPermissionsException();
}
}
public static int getInteger(CommandContext args, CommandSender sender, int index, int def) throws CommandException {
try {
return args.getInteger(index, def);
}
catch(NumberFormatException e) {
throw new CommandException(ComponentRenderers.toLegacyText(new TranslatableComponent("command.error.invalidNumber", args.getString(index)), sender));
}
}
public static @Nullable Duration getDuration(CommandContext args, int index) throws CommandException {
return getDuration(args, index, null);
}
public static Duration getDuration(CommandContext args, int index, Duration def) throws CommandException {
return getDuration(args.getString(index, null), def);
}
public static @Nullable Duration getDuration(String text) throws CommandException {
return getDuration(text, null);
}
public static Duration getDuration(String text, Duration def) throws CommandException {
if(text == null) {
return def;
} else {
try {
return TimeUtils.parseDuration(text);
} catch(DateTimeParseException e) {
throw new TranslatableCommandException("command.error.invalidTimePeriod", text);
}
}
}
public static @Nullable <E extends Enum<E>> E getEnum(CommandContext args, CommandSender sender, int index, Class<E> type) throws CommandException {
return getEnum(args, sender, index, type, null);
}
public static <E extends Enum<E>> E getEnum(CommandContext args, CommandSender sender, int index, Class<E> type, E def) throws CommandException {
return getEnum(args.getString(index, null), sender, type, def);
}
public static <E extends Enum<E>> E getEnum(String text, CommandSender sender, Class<E> type, E def) throws CommandException {
if(text == null) {
return def;
} else {
try {
return Enum.valueOf(type, text.toUpperCase().replace(' ', '_'));
} catch(IllegalArgumentException e) {
throw newCommandException(sender, new TranslatableComponent("command.error.invalidEnum", text));
}
}
}
public static String getDisplayName(CommandSender target) {
return getDisplayName(target, null);
}
public static String getDisplayName(CommandSender target, CommandSender viewer) {
if(target instanceof Player) {
return ((Player) target).getDisplayName(viewer);
} else {
return CONSOLE_DISPLAY_NAME;
}
}
public static String getDisplayName(@Nullable PlayerId target) {
return getDisplayName(target, null);
}
public static String getDisplayName(@Nullable PlayerId target, CommandSender viewer) {
if(target == null) {
return CONSOLE_DISPLAY_NAME;
} else {
Player targetPlayer = Bukkit.getPlayerExact(target.username(), viewer);
if(targetPlayer == null) {
return ChatColor.DARK_AQUA + target.username();
} else {
return targetPlayer.getDisplayName(viewer);
}
}
}
public static String getDisplayName(@Nullable String username) {
return getDisplayName(username, null);
}
public static String getDisplayName(@Nullable String username, CommandSender viewer) {
if(username == null || username.trim().length() == 0 || username.trim().equalsIgnoreCase("CONSOLE")) {
return CONSOLE_DISPLAY_NAME;
} else {
Player targetPlayer = Bukkit.getPlayerExact(username, viewer);
if(targetPlayer == null) {
return ChatColor.DARK_AQUA + username;
} else {
return targetPlayer.getDisplayName(viewer);
}
}
}
public static String formatServerPrefix(Server server) {
return ChatColor.WHITE + "[" +
ChatColor.GOLD + server.name() +
ChatColor.WHITE + "]";
}
public static void notEnoughArguments(CommandSender sender) throws CommandException {
throw new CommandException(Translations.get().t("command.error.notEnoughArguments", sender));
}
}