diff --git a/src/main/java/me/unurled/sacredrealms/sr/commands/admin/AttributeCommand.java b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/AttributeCommand.java new file mode 100644 index 0000000..08c960c --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/AttributeCommand.java @@ -0,0 +1,239 @@ +package me.unurled.sacredrealms.sr.commands.admin; + +import static me.unurled.sacredrealms.sr.utils.Component.comp; +import static me.unurled.sacredrealms.sr.utils.NumberParser.format; +import static me.unurled.sacredrealms.sr.utils.NumberParser.parse; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import me.unurled.sacredrealms.sr.components.attributes.Attribute; +import me.unurled.sacredrealms.sr.components.player.PlayerManager; +import me.unurled.sacredrealms.sr.components.player.SRPlayer; +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 org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class AttributeCommand implements TabExecutor { + + @Nullable + private static SRPlayer getSrPlayer(@NotNull CommandSender sender, Player target) { + PlayerManager pm = (PlayerManager) PlayerManager.getInstance(PlayerManager.class); + if (pm == null) { + sender.sendMessage(comp("An error occurred.")); + return null; + } + SRPlayer player = pm.getPlayer(target.getUniqueId()); + if (player == null) { + sender.sendMessage(comp("An error occurred.")); + return null; + } + return player; + } + + /** + * Executes the given command, returning its success.
+ * If false is returned, then the "usage" plugin.yml entry for this command (if defined) will be + * sent to the player. + * + * @param sender Source of the command + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args Passed command arguments + * @return true if a valid command, otherwise false + */ + @Override + public boolean onCommand( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + // set, get, remove + if (!sender.hasPermission("sr.attributes")) { + sender.sendMessage("Unknown command. Type \"/help\" for help."); + return true; + } + if (args.length <= 2) { + sender.sendMessage( + "Usage: /attribute [value]"); + return true; + } + if (args[0].equals("set") && args.length < 4) { + sender.sendMessage("Usage: /attribute set "); + return true; + } + if (args[1].equals("item-in-hand")) { + if (!(sender instanceof Player target)) { + sender.sendMessage("You must be a player to use this command."); + return true; + } + Attribute attribute; + try { + attribute = Attribute.valueOf(args[2].toUpperCase()); + } catch (IllegalArgumentException e) { + sender.sendMessage("Attribute not found."); + return true; + } + + if (args[0].equalsIgnoreCase("set")) { + try { + double value = parse(args[3]); + if (value < attribute.getMinValue() || value > attribute.getMaxValue()) { + sender.sendMessage( + "Value out of bounds. Min: " + + attribute.getMinValue() + + ", Max: " + + attribute.getMaxValue()); + return true; + } + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + player.setHandItemAttribute(attribute, value); + sender.sendMessage( + "Set " + attribute.getName() + " to " + format(value) + " for " + target.getName()); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid value."); + } + } else if (args[0].equalsIgnoreCase("get")) { + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + sender.sendMessage( + "Get " + + attribute.getName() + + " for " + + target.getName() + + ":" + + " " + + player.getHandItemAttribute(attribute)); + } else if (args[0].equalsIgnoreCase("remove")) { + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + player.removeHandItemAttribute(attribute); + sender.sendMessage("Removed " + attribute.getName() + " for " + target.getName()); + } else { + sender.sendMessage("Usage: /attribute [value]"); + } + return true; + } + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { + sender.sendMessage("Player not found."); + return true; + } + + Attribute attribute; + try { + attribute = Attribute.valueOf(args[2].toUpperCase()); + } catch (IllegalArgumentException e) { + sender.sendMessage("Attribute not found."); + return true; + } + + if (args[0].equalsIgnoreCase("set")) { + try { + double value = parse(args[3]); + if (value < attribute.getMinValue() || value > attribute.getMaxValue()) { + sender.sendMessage( + "Value out of bounds. Min: " + + attribute.getMinValue() + + ", Max: " + + attribute.getMaxValue()); + return true; + } + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + player.setAttribute(attribute, value); + sender.sendMessage( + "Set " + attribute.getName() + " to " + format(value) + " for " + target.getName()); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid value."); + } + } else if (args[0].equalsIgnoreCase("get")) { + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + sender.sendMessage( + "Get " + + attribute.getName() + + " for " + + target.getName() + + ": " + + player.getAttribute(attribute)); + } else if (args[0].equalsIgnoreCase("remove")) { + SRPlayer player = getSrPlayer(sender, target); + if (player == null) return true; + player.removeAttribute(attribute); + sender.sendMessage("Removed " + attribute.getName() + " for " + target.getName()); + } else { + sender.sendMessage("Usage: /attribute [value]"); + } + + return true; + } + + /** + * Requests a list of possible completions for a command argument. + * + * @param sender Source of the command. For players tab-completing a command inside of a command + * block, this will be the player, not the command block. + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args The arguments passed to the command, including final partial argument to be + * completed + * @return A List of possible completions for the final argument, or null to default to the + * command executor + */ + @Override + public @Nullable List onTabComplete( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + if (!sender.hasPermission("sr.attributes")) { + return null; + } + if (args.length == 1) { + return List.of("set", "get", "remove"); + } + if (args.length == 2) { + List players = + Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); + players.add("item-in-hand"); + return players; + } + + if (args.length == 3) { + List attributes = + Arrays.stream(Attribute.values()).map(Attribute::getName).collect(Collectors.toList()); + attributes.removeIf(s -> !s.startsWith(args[2])); + return attributes; + } + if (args.length == 4 && args[0].equalsIgnoreCase("set")) { + Attribute attribute; + try { + attribute = Attribute.valueOf(args[2].toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + try { + if (parse(args[3]) > attribute.getMaxValue() || parse(args[3]) < attribute.getMinValue()) { + return null; + } + } catch (NumberFormatException e) { + return null; + } + + List values = new java.util.ArrayList<>(); + double currentValue = attribute.getMinValue(); + while (currentValue <= attribute.getMaxValue()) { + values.add(String.valueOf(format(currentValue))); + currentValue *= 10; + } + return values; + } + return null; + } +}