diff --git a/Movecraft/build.gradle.kts b/Movecraft/build.gradle.kts index 683722e23..e5b93d389 100644 --- a/Movecraft/build.gradle.kts +++ b/Movecraft/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { runtimeOnly(project(":movecraft-v1_21", "reobf")) implementation(project(":movecraft-api")) compileOnly("org.yaml:snakeyaml:2.0") + implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT") } tasks.shadowJar { @@ -25,7 +26,11 @@ tasks.shadowJar { include(project(":movecraft-v1_18")) include(project(":movecraft-v1_20")) include(project(":movecraft-v1_21")) + include(dependency("co.aikar:acf-paper:0.5.1-SNAPSHOT")) } + + relocate("co.aikar.commands", "Movecraft.acf") + relocate("co.aikar.locales", "Movecraft.locales") } tasks.processResources { diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java index fe69859c1..090676184 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/Movecraft.java @@ -23,7 +23,6 @@ import net.countercraft.movecraft.config.Settings; import net.countercraft.movecraft.craft.ChunkManager; import net.countercraft.movecraft.craft.CraftManager; -import net.countercraft.movecraft.craft.datatag.CraftDataTagRegistry; import net.countercraft.movecraft.features.contacts.ContactsCommand; import net.countercraft.movecraft.features.contacts.ContactsManager; import net.countercraft.movecraft.features.contacts.ContactsSign; @@ -198,16 +197,7 @@ public void onEnable() { getServer().getPluginManager().registerEvents(new InteractListener(), this); - getCommand("movecraft").setExecutor(new MovecraftCommand()); - getCommand("release").setExecutor(new ReleaseCommand()); - getCommand("pilot").setExecutor(new PilotCommand()); - getCommand("rotate").setExecutor(new RotateCommand()); - getCommand("cruise").setExecutor(new CruiseCommand()); - getCommand("craftreport").setExecutor(new CraftReportCommand()); - getCommand("manoverboard").setExecutor(new ManOverboardCommand()); - getCommand("scuttle").setExecutor(new ScuttleCommand()); - getCommand("crafttype").setExecutor(new CraftTypeCommand()); - getCommand("craftinfo").setExecutor(new CraftInfoCommand()); + initializeCommands(); getServer().getPluginManager().registerEvents(new BlockListener(), this); getServer().getPluginManager().registerEvents(new PlayerListener(), this); @@ -244,6 +234,21 @@ public void onEnable() { logger.info("[V " + getDescription().getVersion() + "] has been enabled."); } + private void initializeCommands() { + MovecraftCommandManager movecraftCommandManager = new MovecraftCommandManager(this); + + movecraftCommandManager.registerCommand(new MovecraftCommand()); + movecraftCommandManager.registerCommand(new CraftInfoCommand()); + movecraftCommandManager.registerCommand(new CraftReportCommand()); + movecraftCommandManager.registerCommand(new CraftTypeCommand()); + movecraftCommandManager.registerCommand(new CruiseCommand()); + movecraftCommandManager.registerCommand(new ManOverboardCommand()); + movecraftCommandManager.registerCommand(new PilotCommand()); + movecraftCommandManager.registerCommand(new ReleaseCommand()); + movecraftCommandManager.registerCommand(new RotateCommand()); + movecraftCommandManager.registerCommand(new ScuttleCommand()); + } + @Override public void onLoad() { super.onLoad(); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftInfoCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftInfoCommand.java index 92fd2cfe3..0e1d69440 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftInfoCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftInfoCommand.java @@ -1,23 +1,24 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.InvalidCommandArgument; +import co.aikar.commands.annotation.*; import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.TopicPaginator; -import org.bukkit.command.Command; +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.OptionalInt; import java.util.function.Function; -public class CraftInfoCommand implements TabExecutor { +@CommandAlias("craftinfo") +public class CraftInfoCommand extends BaseCommand { private static final List>> providers = new ArrayList<>(); static { registerMultiProvider(CraftInfoCommand::allowedBlockProvider); @@ -48,51 +49,48 @@ public static void registerProvider(@NotNull Function provider){ providers.add(provider.andThen(List::of)); } + @Default + @Syntax("[player] ") + @Description("Get information on a piloted craft") + @CommandCompletion("@players") + public static void onOtherPlayer(CommandSender commandSender, String[] args) { + if (args.length > 2) { + throw new InvalidCommandArgument("Max allowed arguments: 2"); + } - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if(args.length == 0){ - if (!(sender instanceof Player)){ - sender.sendMessage("Supply a parameter."); - return true; + try { + int page = args.length == 0 ? 1 : Integer.parseInt(args[0]); + if (!(commandSender instanceof Player player)) { + commandSender.sendMessage("You can't run this command on yourself as console"); + return; } - Craft craft = CraftManager.getInstance().getCraftByPlayer(((Player) sender)); - if(craft == null){ - sender.sendMessage("You must be piloting a craft."); - return true; + + Craft craft = CraftManager.getInstance().getCraftByPlayer(player); + if (craft == null) { + commandSender.sendMessage("No player craft found"); + return; } - craftInfo(sender, craft, 1); - return true; - } - OptionalInt pageQuery; - if (sender instanceof Player && (pageQuery = MathUtils.parseInt(args[0])).isPresent()){ - Craft craft = CraftManager.getInstance().getCraftByPlayer(((Player) sender)); - if(craft == null){ - sender.sendMessage("You must be piloting a craft."); - return true; + + craftInfo(commandSender, craft, page); + + } catch (NumberFormatException e) { + Player playerSubject = Bukkit.getPlayer(args[0]); + if (playerSubject == null) { + commandSender.sendMessage("First argument must be either a number or a player"); + return; } - craftInfo(sender, craft, pageQuery.getAsInt()); - return true; - } - var craft = CraftManager.getInstance().getCraftByPlayerName(args[0]); - if (craft == null) { - sender.sendMessage("No player found"); - return true; - } - if(args.length > 1){ - pageQuery = MathUtils.parseInt(args[1]); - if(pageQuery.isEmpty()){ - sender.sendMessage("Parameter " + args[1] + " must be a page number."); - return true; + + Craft craft = CraftManager.getInstance().getCraftByPlayer(playerSubject); + if (craft == null) { + commandSender.sendMessage("No player craft found"); + return; } - } else { - pageQuery = OptionalInt.of(1); + + craftInfo(commandSender, craft, args.length == 1 ? 1 : Integer.parseInt(args[1])); } - craftInfo(sender, craft, pageQuery.getAsInt()); - return true; } - public void craftInfo(@NotNull CommandSender commandSender, @NotNull Craft craft, int page){ + public static void craftInfo(@NotNull CommandSender commandSender, @NotNull Craft craft, int page){ TopicPaginator paginator = new TopicPaginator("Craft Info"); for(var provider : providers){ for(var line : provider.apply(craft)){ @@ -106,9 +104,4 @@ public void craftInfo(@NotNull CommandSender commandSender, @NotNull Craft craft for(String line : paginator.getPage(page)) commandSender.sendMessage(line); } - - @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - return null; - } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftReportCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftReportCommand.java index 8fcddb9e0..f3d685ad5 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftReportCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftReportCommand.java @@ -1,5 +1,7 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.*; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.PilotedCraft; @@ -11,45 +13,36 @@ import net.countercraft.movecraft.util.hitboxes.HitBox; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -public class CraftReportCommand implements CommandExecutor { - @Override - public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] args) { - if (commandSender.getName().equalsIgnoreCase("craftreport")) - return false; +@CommandAlias("craftreport") +@CommandPermission("movecraft.commands,movecraft.commands.craftreport") +public class CraftReportCommand extends BaseCommand { - if (!commandSender.hasPermission("movecraft.commands") - || !commandSender.hasPermission("movecraft.commands.craftreport")) { - commandSender.sendMessage(Component.empty() - .append(ChatUtils.errorPrefix()) - .append(I18nSupport.getInternationalisedComponent("Insufficient Permissions"))); - return true; - } + @Default + @Syntax("") + @Description("Reports on all active craft") + public static void onCommand(CommandSender commandSender, @Optional String pageString) { int page; try { - if (args.length == 0) + if (pageString == null) page = 1; else - page = Integer.parseInt(args[0]); - } - catch (NumberFormatException e) { + page = Integer.parseInt(pageString); + } catch (NumberFormatException e) { commandSender.sendMessage(Component.empty() .append(ChatUtils.commandPrefix()) .append(I18nSupport.getInternationalisedComponent("Paginator - Invalid Page")) .append(Component.text("\"")) - .append(Component.text(args[0])) + .append(Component.text(pageString)) .append(Component.text("\""))); - return true; + return; } if (CraftManager.getInstance().isEmpty()) { commandSender.sendMessage(Component.empty() .append(ChatUtils.commandPrefix()) .append(I18nSupport.getInternationalisedComponent("Craft Report - None Found"))); - return true; + return; } ComponentPaginator paginator = new ComponentPaginator( I18nSupport.getInternationalisedComponent("Craft Report"), @@ -87,12 +80,11 @@ else if (craft.getDisabled()) .append(ChatUtils.commandPrefix()) .append(I18nSupport.getInternationalisedComponent("Paginator - Invalid page")) .append(Component.text(" \"")) - .append(Component.text(args[0])) + .append(Component.text(page)) .append(Component.text("\""))); - return true; + return; } for (Component line : paginator.getPage(page)) commandSender.sendMessage(line); - return true; } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftTypeCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftTypeCommand.java index 3b08b64b6..c5bedf070 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftTypeCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CraftTypeCommand.java @@ -1,99 +1,79 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.InvalidCommandArgument; +import co.aikar.commands.annotation.*; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; -import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.TopicPaginator; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.util.ChatPaginator; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.Optional; -import java.util.OptionalInt; -public class CraftTypeCommand implements TabExecutor { +@CommandAlias("crafttype") +@CommandPermission("movecraft.commands") +public class CraftTypeCommand extends BaseCommand { private static final Field[] craftTypeFields; + static { craftTypeFields = CraftType.class.getDeclaredFields(); - for(var field : craftTypeFields){ + for (var field : craftTypeFields) { field.setAccessible(true); } } - @Override - public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - CraftType type; - int page; - if(args.length == 0 || (args.length == 1 && MathUtils.parseInt(args[0]).isPresent())) { - Optional typeQuery = tryGetCraftFromPlayer(commandSender); - if(typeQuery.isEmpty()){ - commandSender.sendMessage("You must supply a craft type!"); - return true; - } - type = typeQuery.get(); - page = args.length == 0 ? 1 : MathUtils.parseInt(args[0]).getAsInt(); + @Syntax("") + @Subcommand("list") + public static void listCrafts(CommandSender commandSender, @Default("1") int page) { + sendTypeListPage(page, commandSender); + } + + @Default + @Syntax("[list|CRAFTTYPE] ") + @Description("Get information on a specific craft type") + @CommandCompletion("@crafttypes") + public static void onCommand(@NotNull CommandSender commandSender, String[] args) { + if (args.length > 2) { + throw new InvalidCommandArgument("Max allowed arguments: 2"); } - else { - if(args.length > 1) { - OptionalInt pageQuery = MathUtils.parseInt(args[1]); - if(pageQuery.isEmpty()){ - commandSender.sendMessage("Argument " + args[1] + " must be a page number"); - return true; - } - page = pageQuery.getAsInt(); + + try { + int page = args.length == 0 ? 1 : Integer.parseInt(args[0]); + Optional type = tryGetCraftFromPlayer(commandSender); + if (type.isEmpty()) { + commandSender.sendMessage("Craft not found!"); + return; } - else { - page = 1; + + sendTypePage(type.get(), page, commandSender); + } catch (NumberFormatException e) { + CraftType type = CraftManager.getInstance().getCraftTypeFromString(args[0]); + if (type == null) { + commandSender.sendMessage("First argument must be either a number or a craft"); + return; } - if(args[0].equalsIgnoreCase("list")) { - sendTypeListPage(page, commandSender); - return true; + + if (!commandSender.hasPermission("movecraft." + type.getStringProperty(CraftType.NAME) + ".pilot")) { + commandSender.sendMessage("You don't have permission for that craft type!"); + return; } - type = CraftManager.getInstance().getCraftTypeFromString(args[0]); - } - if(type == null) { - commandSender.sendMessage("You must supply a craft type!"); - return true; - } - if(!commandSender.hasPermission("movecraft." + type.getStringProperty(CraftType.NAME) + ".pilot")) { - commandSender.sendMessage("You don't have permission for that craft type!"); - return true; + + int page = args.length == 1 ? 1 : Integer.parseInt(args[1]); + sendTypePage(type, page, commandSender); } - sendTypePage(type, page, commandSender); - return true; - } - @Nullable - @Override - public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) { - if(strings.length !=1 || !commandSender.hasPermission("movecraft.commands") || !commandSender.hasPermission("movecraft.commands.crafttype")) - return Collections.emptyList(); - List completions = new ArrayList<>(); - for(CraftType type : CraftManager.getInstance().getCraftTypes()) - if(commandSender.hasPermission("movecraft." + type.getStringProperty(CraftType.NAME) + ".pilot")) - completions.add(type.getStringProperty(CraftType.NAME)); - completions.add("list"); - List returnValues = new ArrayList<>(); - for(String completion : completions) - if(completion.toLowerCase().startsWith(strings[strings.length-1].toLowerCase())) - returnValues.add(completion); - return returnValues; } - private void sendTypePage(@NotNull CraftType type, int page, @NotNull CommandSender commandSender){ + private static void sendTypePage(@NotNull CraftType type, int page, @NotNull CommandSender commandSender) { TopicPaginator paginator = new TopicPaginator("Type Info"); - for(var field : craftTypeFields){ - if(field.getName().equals("data")){ // don't include the backing data object + for (var field : craftTypeFields) { + if (field.getName().equals("data")) { // don't include the backing data object continue; } Object value; @@ -104,40 +84,40 @@ private void sendTypePage(@NotNull CraftType type, int page, @NotNull CommandSe continue; } var repr = field.getName() + ": " + value; - if(repr.length() > ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH){ + if (repr.length() > ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH) { paginator.addLine(field.getName() + ": too long"); } else { paginator.addLine(field.getName() + ": " + value); } } - if(!paginator.isInBounds(page)){ + if (!paginator.isInBounds(page)) { commandSender.sendMessage(String.format("Page %d is out of bounds.", page)); return; } - for(String line : paginator.getPage(page)) + for (String line : paginator.getPage(page)) commandSender.sendMessage(line); } - private void sendTypeListPage(int page, @NotNull CommandSender commandSender){ + private static void sendTypeListPage(int page, @NotNull CommandSender commandSender) { TopicPaginator paginator = new TopicPaginator("Type Info"); - for(var entry : CraftManager.getInstance().getCraftTypes()){ + for (var entry : CraftManager.getInstance().getCraftTypes()) { paginator.addLine(entry.getStringProperty(CraftType.NAME)); } - if(!paginator.isInBounds(page)){ + if (!paginator.isInBounds(page)) { commandSender.sendMessage(String.format("Page %d is out of bounds.", page)); return; } - for(String line : paginator.getPage(page)) + for (String line : paginator.getPage(page)) commandSender.sendMessage(line); } @NotNull - private Optional tryGetCraftFromPlayer(CommandSender commandSender){ + private static Optional tryGetCraftFromPlayer(CommandSender commandSender) { if (!(commandSender instanceof Player)) { return Optional.empty(); } Craft c = CraftManager.getInstance().getCraftByPlayer((Player) commandSender); - if(c == null){ + if (c == null) { return Optional.empty(); } return Optional.of(c.getType()); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CruiseCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CruiseCommand.java index 2e890508a..112aca1b7 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/CruiseCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/CruiseCommand.java @@ -1,78 +1,25 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.*; import net.countercraft.movecraft.CruiseDirection; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class CruiseCommand implements TabExecutor { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { - if(!command.getName().equalsIgnoreCase("cruise")){ - return false; - } - if(!(commandSender instanceof Player)){ - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Cruise - Must Be Player")); - return true; - } - Player player = (Player) commandSender; - - if(args.length<1){ - final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); - if (craft == null) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return true; - } - if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.cruise")) { - craft.setCruising(false); - return true; - } - - if(craft.getCruising()){ - craft.setCruising(false); - return true; - } - // Normalize yaw from [-360, 360] to [0, 360] - float yaw = (player.getLocation().getYaw() + 360.0f); - if (yaw >= 360.0f) { - yaw %= 360.0f; - } - if (yaw >= 45 && yaw < 135) { // west - craft.setCruiseDirection(CruiseDirection.WEST); - } else if (yaw >= 135 && yaw < 225) { // north - craft.setCruiseDirection(CruiseDirection.NORTH); - } else if (yaw >= 225 && yaw <= 315){ // east - craft.setCruiseDirection(CruiseDirection.EAST); - } else { // default south - craft.setCruiseDirection(CruiseDirection.SOUTH); - } - craft.setCruising(true); - return true; - } - if (args[0].equalsIgnoreCase("off")) { //This goes before because players can sometimes freeze while cruising - final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); - if (craft == null) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return true; - } - craft.setCruising(false); - return true; - } - if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.cruise")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); +@CommandAlias("cruise") +@CommandPermission("movecraft.commands,movecraft.commands.cruise") +public class CruiseCommand extends BaseCommand { + + @PreCommand + public static boolean preCommand(CommandSender sender) { + if(!(sender instanceof Player player)) return true; - } final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); if (craft == null) { @@ -89,66 +36,61 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, return true; } + return false; + } - if (args[0].equalsIgnoreCase("on")) { - float yaw = (player.getLocation().getYaw() + 360.0f); - if (yaw >= 360.0f) { - yaw %= 360.0f; - } - if (yaw >= 45 && yaw < 135) { // west - craft.setCruiseDirection(CruiseDirection.WEST); - } else if (yaw >= 135 && yaw < 225) { // north - craft.setCruiseDirection(CruiseDirection.NORTH); - } else if (yaw >= 225 && yaw <= 315){ // east - craft.setCruiseDirection(CruiseDirection.EAST); - } else { // default south - craft.setCruiseDirection(CruiseDirection.SOUTH); - } - craft.setCruising(true); - return true; - } - if (args[0].equalsIgnoreCase("north") || args[0].equalsIgnoreCase("n")) { - craft.setCruiseDirection(CruiseDirection.NORTH); - craft.setCruising(true); - return true; - } - if (args[0].equalsIgnoreCase("south") || args[0].equalsIgnoreCase("s")) { - craft.setCruiseDirection(CruiseDirection.SOUTH); + @Default + @Syntax("[on|off|DIRECTION]") + @CommandCompletion("@directions") + @Description("Starts your craft cruising") + public static void onCommand(Player player, @Optional CruiseDirection direction) { + final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + + //Resolver returns NONE on resolver fail, null if no argument at all + if (direction != null && direction != CruiseDirection.NONE) { + craft.setCruiseDirection(direction); craft.setCruising(true); - return true; + return; + } else if(craft.getCruising()) { + craft.setCruising(false); + return; } - if (args[0].equalsIgnoreCase("east") || args[0].equalsIgnoreCase("e")) { - craft.setCruiseDirection(CruiseDirection.EAST); - craft.setCruising(true); - return true; + + yawLocationCruising(player, craft); + } + + @Subcommand("off") + public static void offCruising(Player player) { + final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + if (craft == null) { + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); + return; } - if (args[0].equalsIgnoreCase("west") || args[0].equalsIgnoreCase("w")) { + + craft.setCruising(false); + } + + @Subcommand("on") + public static void onCruising(Player player) { + final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + yawLocationCruising(player, craft); + } + + private static void yawLocationCruising(Player player, Craft craft) { + + // Normalize yaw from [-360, 360] to [0, 360] + float yaw = (player.getLocation().getYaw() + 360.0f) % 360.0f; + + if (yaw >= 45 && yaw < 135) { // west craft.setCruiseDirection(CruiseDirection.WEST); - craft.setCruising(true); - return true; - } - if (args[0].equalsIgnoreCase("up") || args[0].equalsIgnoreCase("u")) { - craft.setCruiseDirection(CruiseDirection.UP); - craft.setCruising(true); - return true; - } - if (args[0].equalsIgnoreCase("down") || args[0].equalsIgnoreCase("d")) { - craft.setCruiseDirection(CruiseDirection.DOWN); - craft.setCruising(true); - return true; + } else if (yaw >= 135 && yaw < 225) { // north + craft.setCruiseDirection(CruiseDirection.NORTH); + } else if (yaw >= 225 && yaw <= 315){ // east + craft.setCruiseDirection(CruiseDirection.EAST); + } else { // default south + craft.setCruiseDirection(CruiseDirection.SOUTH); } - return false; - } - private final String[] completions = {"North", "East", "South", "West", "Up", "Down", "On", "Off"}; - @Override - public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { - if(strings.length !=1) - return Collections.emptyList(); - List returnValues = new ArrayList<>(); - for(String completion : completions) - if(completion.toLowerCase().startsWith(strings[strings.length-1].toLowerCase())) - returnValues.add(completion); - return returnValues; + craft.setCruising(true); } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ManOverboardCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ManOverboardCommand.java index 98882f49c..caae20d44 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ManOverboardCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ManOverboardCommand.java @@ -1,5 +1,9 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Description; import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.config.Settings; import net.countercraft.movecraft.craft.Craft; @@ -10,41 +14,31 @@ import net.countercraft.movecraft.util.MathUtils; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class ManOverboardCommand implements CommandExecutor { +@CommandAlias("manoverboard") +public class ManOverboardCommand extends BaseCommand { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { - if (!command.getName().equalsIgnoreCase("manOverBoard")) - return false; + @Default + @Description("If enabled, returns you to a craft you have fallen out of") + public static void onCommand(Player player) { - if (!(commandSender instanceof Player)) { - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("ManOverboard - Must Be Player")); - return true; - } - Player player = (Player) commandSender; Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); - if (craft == null) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("ManOverboard - No Craft Found")); - return true; + return; } Location telPoint = getCraftTeleportPoint(craft); if (craft.getWorld() != player.getWorld()) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("ManOverboard - Other World")); - return true; + return; } if ((System.currentTimeMillis() - @@ -52,19 +46,19 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, && !MathUtils.locIsNearCraftFast(craft, MathUtils.bukkit2MovecraftLoc(player.getLocation()))) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("ManOverboard - Timed Out")); - return true; + return; } if (telPoint.distanceSquared(player.getLocation()) > Settings.ManOverboardDistSquared) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("ManOverboard - Distance Too Far")); - return true; + return; } if (craft.getDisabled() || craft instanceof SinkingCraft) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("ManOverboard - Disabled")); - return true; + return; } ManOverboardEvent event = new ManOverboardEvent(craft, telPoint); @@ -75,10 +69,9 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, player.setVelocity(new Vector(0, 0, 0)); player.setFallDistance(0); Movecraft.getInstance().getSmoothTeleport().teleport(player, telPoint); - return true; } - private @NotNull Location getCraftTeleportPoint(@NotNull Craft craft) { + private static @NotNull Location getCraftTeleportPoint(@NotNull Craft craft) { double telX = ((craft.getHitBox().getMinX() + craft.getHitBox().getMaxX()) / 2D) + 0.5D; double telZ = ((craft.getHitBox().getMinZ() + craft.getHitBox().getMaxZ()) / 2D) + 0.5D; double telY = craft.getHitBox().getMaxY() + 1; diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java index 6bb739cbd..993b88534 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommand.java @@ -1,56 +1,32 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.*; import net.countercraft.movecraft.Movecraft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.plugin.PluginDescriptionFile; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class MovecraftCommand implements TabExecutor { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { - if (!command.getName().equalsIgnoreCase("movecraft")) { - return false; - } - if(!commandSender.hasPermission("movecraft.commands.movecraft")){ - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - - if(args.length == 0){ - PluginDescriptionFile descriptionFile = Movecraft.getInstance().getDescription(); - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + "Movecraft " + descriptionFile.getVersion() + " by " + descriptionFile.getAuthors()); - return true; - } - - if(args.length==1 && args[0].equalsIgnoreCase("reloadtypes") && commandSender.hasPermission("movecraft.commands.movecraft.reloadtypes")){ - CraftManager.getInstance().reloadCraftTypes(); - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Movecraft - Reloaded Types")); - return true; - } - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Movecraft - Invalid Argument")); - return true; +@CommandAlias("movecraft") +@CommandPermission("movecraft.commands.movecraft") +public class MovecraftCommand extends BaseCommand { + @Default + @Syntax("") + @Description("Base movecraft command") + public static void displayAuthors(CommandSender commandSender) { + PluginDescriptionFile descriptionFile = Movecraft.getInstance().getDescription(); + commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + "Movecraft " + descriptionFile.getVersion() + " by " + descriptionFile.getAuthors()); } - @Override - public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) { - if(args.length !=1 || !commandSender.hasPermission("movecraft.commands") || !commandSender.hasPermission("movecraft.commands.movecraft")) - return Collections.emptyList(); - List completions = new ArrayList<>(); - completions.add("reloadtypes"); - List returnValues = new ArrayList<>(); - for(String completion : completions) - if(completion.toLowerCase().startsWith(args[args.length-1].toLowerCase())) - returnValues.add(completion); - return returnValues; + @CommandPermission("movecraft.commands.movecraft.reloadtypes") + @Subcommand("reloadtypes") + @Description("Reload craft types from file.") + public static void reloadTypes(CommandSender commandSender) { + CraftManager.getInstance().reloadCraftTypes(); + commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Movecraft - Reloaded Types")); } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommandManager.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommandManager.java new file mode 100644 index 000000000..eb9215832 --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/MovecraftCommandManager.java @@ -0,0 +1,97 @@ +package net.countercraft.movecraft.commands; + +import co.aikar.commands.CommandIssuer; +import co.aikar.commands.ConditionFailedException; +import co.aikar.commands.InvalidCommandArgument; +import co.aikar.commands.PaperCommandManager; +import net.countercraft.movecraft.CruiseDirection; +import net.countercraft.movecraft.craft.CraftManager; +import net.countercraft.movecraft.craft.type.CraftType; +import net.countercraft.movecraft.localisation.I18nSupport; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; + +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; + +public class MovecraftCommandManager extends PaperCommandManager { + public MovecraftCommandManager(Plugin plugin) { + super(plugin); + this.registerMovecraftCompletions(); + this.registerMovecraftContexts(); + this.registerMovecraftConditions(); + } + + private static final Pattern COMMA = Pattern.compile(","); + private static final Pattern PIPE = Pattern.compile("\\|"); + + @Override //gonna keep this in case it is actually used + public boolean hasPermission(CommandIssuer issuer, String permission) { + if (permission == null || permission.isEmpty()) { + return true; + } + + //handle AND like normal using comma "," + String[] perms = COMMA.split(permission); + if (perms.length > 1) { + return super.hasPermission(issuer, Set.of(perms)); + } + + //handle OR using pipe "|" + CommandSender sender = issuer.getIssuer(); + for (String perm : PIPE.split(permission)) { + perm = perm.trim(); + if (!perm.isEmpty() && sender.hasPermission(perm)) { + return true; + } + } + + return false; + } + + private void registerMovecraftCompletions() { + getCommandCompletions().registerCompletion("crafttypes", c -> { + Set craftTypes = CraftManager.getInstance().getCraftTypes(); + List craftNames = craftTypes.stream().map(type -> type.getStringProperty(CraftType.NAME)).toList(); + return craftNames; + }); + + getCommandCompletions().registerCompletion("directions", c -> { + var allDirections = CruiseDirection.valuesString(); + var allButNone = allDirections.stream().filter(p -> !p.equals("none")).toList(); + return allButNone; + }); + } + + private void registerMovecraftContexts() { + getCommandContexts().registerContext(CruiseDirection.class, (c) -> { + String data = c.popFirstArg(); + return CruiseDirection.fromString(data); + }); + + getCommandContexts().registerContext(CraftType.class, (c) -> { + String data = c.popFirstArg(); + CraftType type = CraftManager.getInstance().getCraftTypeFromString(data); + + if (type == null) { + throw new InvalidCommandArgument("You must supply a craft type!"); + } + + return type; + }); + } + + private void registerMovecraftConditions() { + getCommandConditions().addCondition("pilot_others", (context -> { + var issuer = context.getIssuer(); + if (!issuer.hasPermission("movecraft.commands.release.others")) { + throw new ConditionFailedException(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("Release - No Force Release")); + + } + })); + } +} diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/PilotCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/PilotCommand.java index 2f0d67747..a12f4d8f9 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/PilotCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/PilotCommand.java @@ -1,5 +1,12 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +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.Description; +import co.aikar.commands.annotation.Syntax; import net.countercraft.movecraft.MovecraftLocation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; @@ -11,43 +18,24 @@ import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.Pair; import org.bukkit.World; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.Locale; import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class PilotCommand implements TabExecutor { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { - if (!command.getName().equalsIgnoreCase("pilot")) - return false; - if (!(commandSender instanceof Player)) { - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - Must Be Player")); - return true; - } - Player player = (Player) commandSender; - if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.pilot")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - if (args.length < 1) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - No Craft Type")); - return true; - } - if (!player.hasPermission("movecraft." + args[0] + ".pilot")) { +@CommandAlias("pilot") +@CommandPermission("movecraft.commands,movecraft.commands.pilot") +public class PilotCommand extends BaseCommand { + + @Default + @CommandCompletion("@crafttypes") + @Syntax("[CRAFTTYPE]") + @Description("Pilots the craft at your feet") + public static void onCommand(Player player, CraftType craftType) { + if (!player.hasPermission("movecraft." + craftType.toString().toLowerCase(Locale.ROOT) + ".pilot")) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - CraftType craftType = CraftManager.getInstance().getCraftTypeFromString(args[0]); - if (craftType == null) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Pilot - Invalid Craft Type")); - return true; + return; } final World world = player.getWorld(); @@ -72,25 +60,5 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, CraftManager.getInstance().release(oldCraft, CraftReleaseEvent.Reason.PLAYER, false); } ); - return true; - } - - @Override - public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { - if (strings.length != 1 || !commandSender.hasPermission("movecraft.commands") - || !commandSender.hasPermission("movecraft.commands.pilot")) - return Collections.emptyList(); - - List completions = new ArrayList<>(); - for (CraftType type : CraftManager.getInstance().getCraftTypes()) - if (commandSender.hasPermission("movecraft." + type.getStringProperty(CraftType.NAME) + ".pilot")) - completions.add(type.getStringProperty(CraftType.NAME)); - - List returnValues = new ArrayList<>(); - for (String completion : completions) - if (completion.toLowerCase().startsWith(strings[strings.length-1].toLowerCase())) - returnValues.add(completion); - - return returnValues; } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ReleaseCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ReleaseCommand.java index 0bb0877d8..edf10f424 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ReleaseCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ReleaseCommand.java @@ -1,127 +1,116 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandCompletion; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Conditions; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.PilotedCraft; import net.countercraft.movecraft.events.CraftReleaseEvent; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.Bukkit; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class ReleaseCommand implements TabExecutor { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { - if (!command.getName().equalsIgnoreCase("release")) - return false; +@CommandAlias("release") +@CommandPermission("movecraft.commands,movecraft.commands.release") +public class ReleaseCommand extends BaseCommand { - if (!commandSender.hasPermission("movecraft.commands") - || !commandSender.hasPermission("movecraft.commands.release")) { - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; + @Subcommand("-p") + @Conditions("pilot_others") + public static void releaseAllPlayers(CommandSender commandSender) { + for (Player p : Bukkit.getOnlinePlayers()) { + String name = p.getName(); + final Craft pCraft = CraftManager.getInstance().getCraftByPlayerName(name); + if (pCraft != null) + CraftManager.getInstance().release(pCraft, CraftReleaseEvent.Reason.FORCE, false); + } + + commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("Release - Released All Player Crafts")); + } + + @Subcommand("-a") + @Conditions("pilot_others") + public static void releaseAllCrafts(CommandSender commandSender) { + final List craftsToRelease = new ArrayList<>(CraftManager.getInstance().getCrafts()); + for (Craft craft : craftsToRelease) { + CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.FORCE, false); } + + commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("Release - Released All Crafts")); + } + + @Subcommand("-n") + @Conditions("pilot_others") + public static void releaseAllNullCrafts(CommandSender commandSender) { + final List craftsToRelease = new ArrayList<>(CraftManager.getInstance().getCrafts()); + for (Craft craft : craftsToRelease) { + if (!(craft instanceof PilotedCraft)) + CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.FORCE, false); + } + + commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + + I18nSupport.getInternationalisedString("Release - Released All Null Crafts")); + } + + @Default + @Syntax("<-p|-a|-n|player>") + @CommandCompletion("@players") + public static void onCommand(CommandSender commandSender, String[] args) { + if (args.length == 0) { - if(!(commandSender instanceof Player)) { + if(!(commandSender instanceof Player player)) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString( "Player - Error - You do not have a craft to release!")); - return true; + return; } - Player player = (Player) commandSender; - final Craft pCraft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + final Craft pCraft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); if (pCraft == null) { player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString( "Player - Error - You do not have a craft to release!")); - return true; + return; } + CraftManager.getInstance().release(pCraft, CraftReleaseEvent.Reason.PLAYER, false); - return true; + return; } + if (!commandSender.hasPermission("movecraft.commands.release.others")) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Release - No Force Release")); - return true; - } - if (args[0].equalsIgnoreCase("-p")) { - for (Player p : Bukkit.getOnlinePlayers()) { - String name = p.getName(); - final Craft pCraft = CraftManager.getInstance().getCraftByPlayerName(name); - if (pCraft != null) - CraftManager.getInstance().release(pCraft, CraftReleaseEvent.Reason.FORCE, false); - } - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("Release - Released All Player Crafts")); - return true; - } - - if (args[0].equalsIgnoreCase("-a")) { - final List craftsToRelease = new ArrayList<>(CraftManager.getInstance().getCrafts()); - for (Craft craft : craftsToRelease) { - CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.FORCE, false); - } - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("Release - Released All Crafts")); - return true; - } - - if (args[0].equalsIgnoreCase("-n")) { - final List craftsToRelease = new ArrayList<>(CraftManager.getInstance().getCrafts()); - for (Craft craft : craftsToRelease) { - if (!(craft instanceof PilotedCraft)) - CraftManager.getInstance().release(craft, CraftReleaseEvent.Reason.FORCE, false); - } - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX - + I18nSupport.getInternationalisedString("Release - Released All Null Crafts")); - return true; + return; } Player target = Bukkit.getPlayer(args[0]); if (target == null) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Player - Not Found")); - return true; + return; } final Craft pCraft = CraftManager.getInstance().getCraftByPlayerName(args[0]); if (pCraft != null) { CraftManager.getInstance().release(pCraft, CraftReleaseEvent.Reason.FORCE, false); commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Release - Successful Force Release")); - return true; + return; } commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Player - Not Piloting")); - return true; - } - - @Override - public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { - if(strings.length !=1 || !commandSender.hasPermission("movecraft.commands.release.others")) - return Collections.emptyList(); - List completions = new ArrayList<>(); - completions.add("-a"); - completions.add("-p"); - completions.add("-n"); - for(Player player : Bukkit.getOnlinePlayers()) { - completions.add(player.getName()); - } - - List returnValues = new ArrayList<>(); - for(String completion : completions) { - if (completion.toLowerCase().startsWith(strings[strings.length - 1].toLowerCase())) - returnValues.add(completion); - } - return returnValues; } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/RotateCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/RotateCommand.java index 28d7421a2..57114b822 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/RotateCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/RotateCommand.java @@ -1,84 +1,69 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; import net.countercraft.movecraft.MovecraftRotation; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.localisation.I18nSupport; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class RotateCommand implements TabExecutor{ - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) { - if(!command.getName().equalsIgnoreCase("rotate")){ - return false; - } - if(!(commandSender instanceof Player)){ - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Rotation - Must Be Player")); - return true; +@CommandAlias("rotate") +@CommandPermission("movecraft.commands") +public class RotateCommand extends BaseCommand { + + @Subcommand("left") + @CommandPermission("movecraft.commands.rotateleft") + public static void rotateLeft(Player player) { + final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + if(craft==null){ + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); + return; } - Player player = (Player) commandSender; - if(args.length<1){ - commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Rotation - Specify Direction")); - return true; + + if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); + return; } - if (args[0].equalsIgnoreCase("left")) { - if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.rotateleft")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); - if(craft==null){ - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return true; - } - if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - CraftManager.getInstance().getCraftByPlayerName(player.getName()).rotate(MovecraftRotation.ANTICLOCKWISE, craft.getHitBox().getMidPoint()); - return true; + + CraftManager.getInstance().getCraftByPlayerName(player.getName()).rotate(MovecraftRotation.ANTICLOCKWISE, craft.getHitBox().getMidPoint()); + } + + @Subcommand("right") + @CommandPermission("movecraft.commands.rotateright") + public static void rotateRight(Player player) { + final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); + if(craft==null){ + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); + return; } - if (args[0].equalsIgnoreCase("right")) { - if (!player.hasPermission("movecraft.commands") || !player.hasPermission("movecraft.commands.rotateright")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - final Craft craft = CraftManager.getInstance().getCraftByPlayerName(player.getName()); - if(craft==null){ - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return true; - } - if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; - } - CraftManager.getInstance().getCraftByPlayerName(player.getName()).rotate(MovecraftRotation.CLOCKWISE, craft.getHitBox().getMidPoint()); - return true; + if (!player.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".rotate")) { + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); + return; } - player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Rotation - Invalid Direction")); - return true; + + CraftManager.getInstance().getCraftByPlayerName(player.getName()).rotate(MovecraftRotation.CLOCKWISE, craft.getHitBox().getMidPoint()); } - private final String[] completions = {"Right", "Left"}; - @Override - public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { - if(strings.length !=1) - return Collections.emptyList(); - List returnValues = new ArrayList<>(); - for(String completion : completions) - if(completion.toLowerCase().startsWith(strings[strings.length-1].toLowerCase())) - returnValues.add(completion); - return returnValues; + @Default + @Syntax("[left|right]") + @Description("Rotates your craft") + public static void onCommand(Player player, String[] args) { + + if(args.length<1){ + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Rotation - Specify Direction")); + return; + } + + player.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Rotation - Invalid Direction")); } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ScuttleCommand.java b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ScuttleCommand.java index 21ab55248..6399a01b9 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/commands/ScuttleCommand.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/commands/ScuttleCommand.java @@ -1,5 +1,11 @@ package net.countercraft.movecraft.commands; +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandCompletion; +import co.aikar.commands.annotation.Default; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Syntax; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.craft.SinkingCraft; @@ -7,22 +13,19 @@ import net.countercraft.movecraft.events.CraftScuttleEvent; import net.countercraft.movecraft.localisation.I18nSupport; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import static net.countercraft.movecraft.util.ChatUtils.MOVECRAFT_COMMAND_PREFIX; -public class ScuttleCommand implements CommandExecutor { +@CommandAlias("scuttle") +public class ScuttleCommand extends BaseCommand { - - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { - - if (!command.getName().equalsIgnoreCase("scuttle")) { - return false; - } + @Default + @Syntax("") + @Description("Sinks piloted craft") + @CommandCompletion("@players") + public static void onCommand(CommandSender commandSender, String[] strings) { Craft craft = null; // Scuttle other player @@ -31,46 +34,44 @@ public boolean onCommand(CommandSender commandSender, Command command, String s, if (player == null) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Must Be Online")); - return true; + return; } craft = CraftManager.getInstance().getCraftByPlayer(player); } else if (commandSender.hasPermission("movecraft.commands.scuttle.self") && strings.length == 0) { - if (!(commandSender instanceof Player)) { + if (!(commandSender instanceof Player player)) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Must Be Player")); - return true; + return; } - craft = CraftManager.getInstance().getCraftByPlayer(Bukkit.getPlayer(commandSender.getName())); + craft = CraftManager.getInstance().getCraftByPlayer(player); } if (craft == null) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("You must be piloting a craft")); - return true; + return; } if (craft instanceof SinkingCraft) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Craft Already Sinking")); - return true; + return; } if (!commandSender.hasPermission("movecraft." + craft.getType().getStringProperty(CraftType.NAME) + ".scuttle")) { commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Insufficient Permissions")); - return true; + return; } CraftScuttleEvent e = new CraftScuttleEvent(craft, (Player) commandSender); Bukkit.getServer().getPluginManager().callEvent(e); if (e.isCancelled()) - return true; + return; craft.setCruising(false); CraftManager.getInstance().sink(craft); commandSender.sendMessage(MOVECRAFT_COMMAND_PREFIX + I18nSupport.getInternationalisedString("Scuttle - Scuttle Activated")); - return true; - } } diff --git a/api/src/main/java/net/countercraft/movecraft/CruiseDirection.java b/api/src/main/java/net/countercraft/movecraft/CruiseDirection.java index b569903a3..f6a8c5645 100644 --- a/api/src/main/java/net/countercraft/movecraft/CruiseDirection.java +++ b/api/src/main/java/net/countercraft/movecraft/CruiseDirection.java @@ -2,6 +2,11 @@ import org.bukkit.block.BlockFace; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Optional; + public enum CruiseDirection { NORTH((byte) 0x3), //0x3 SOUTH((byte) 0x2), //0x2 @@ -74,5 +79,23 @@ public CruiseDirection getRotated(MovecraftRotation rotation) { case NONE -> this; }; } + + public static CruiseDirection fromString(String input) { + final String sanitized = input.toLowerCase(Locale.ROOT); + + return switch (sanitized) { + case "north", "n" -> CruiseDirection.NORTH; + case "south", "s" -> CruiseDirection.SOUTH; + case "east", "e" -> CruiseDirection.EAST; + case "west", "w" -> CruiseDirection.WEST; + case "up", "u" -> CruiseDirection.UP; + case "down", "d" -> CruiseDirection.DOWN; + default -> CruiseDirection.NONE; + }; + } + + public static List valuesString() { + return Arrays.stream(values()).map(v -> v.toString().toLowerCase(Locale.ROOT)).toList(); + } } diff --git a/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts index 8d453cbd9..812b06a0f 100644 --- a/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts @@ -7,6 +7,7 @@ repositories { maven("https://repo.maven.apache.org/maven2/") maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://repo.papermc.io/repository/maven-public/") + maven("https://repo.aikar.co/content/groups/aikar/") } group = "net.countercraft"