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)); } }