diff --git a/src/main/java/com/extendedclip/deluxemenus/command/subcommand/OpenCommand.java b/src/main/java/com/extendedclip/deluxemenus/command/subcommand/OpenCommand.java index 33cb874c..362a94d9 100644 --- a/src/main/java/com/extendedclip/deluxemenus/command/subcommand/OpenCommand.java +++ b/src/main/java/com/extendedclip/deluxemenus/command/subcommand/OpenCommand.java @@ -10,7 +10,9 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -18,6 +20,8 @@ public class OpenCommand extends SubCommand { private static final String OPEN_COMMAND = "deluxemenus.open"; + private static final String ARGS_MARKER = "-args:"; + private static final String PLACEHOLDER_FLAG = "-p:"; public OpenCommand(final @NotNull DeluxeMenus plugin) { super(plugin); @@ -47,52 +51,68 @@ public void execute(final @NotNull CommandSender sender, final @NotNull List menuArgs = null; + + int index = 1; - placeholderPlayer = arguments.get(1).replace("-p:", ""); + // Optional — only consumed if it isn't the -p: flag or the -args: marker. + // This is what actually fixes "/dm open myArg": myArg no longer gets + // swallowed as a viewer name unless it genuinely occupies the viewer slot + if (index < arguments.size() + && !arguments.get(index).startsWith(PLACEHOLDER_FLAG) + && !arguments.get(index).equals(ARGS_MARKER)) { + viewerName = arguments.get(index); + index++; + } - } else if (arguments.size() >= 3 && arguments.get(2).startsWith("-p:")) { + // Optional -p: flag + if (index < arguments.size() && arguments.get(index).startsWith(PLACEHOLDER_FLAG)) { if (!sender.hasPermission("deluxemenus.placeholdersfor")) { plugin.sms(sender, Messages.NO_PERMISSION_PLAYER_ARGUMENT); return; } - placeholderPlayer = arguments.get(2).replace("-p:", ""); + placeholderPlayerName = arguments.get(index).substring(PLACEHOLDER_FLAG.length()); + index++; } - if (arguments.size() >= 2) { - if (placeholderPlayer == null) { - if (player && !sender.hasPermission("deluxemenus.open.others")) { - plugin.sms(sender, Messages.NO_PERMISSION); - return; + // Once -args: is seen, everything after it is taken as key=value pairs and + if (index < arguments.size() && arguments.get(index).equals(ARGS_MARKER)) { + index++; + menuArgs = new HashMap<>(); + + for (int i = index; i < arguments.size(); i++) { + final String token = arguments.get(i); + final int equalsPos = token.indexOf('='); + + if (equalsPos <= 0) { + // Malformed token (no "=" or starts with "="): skip rather than fail the command. + continue; } - viewer = Bukkit.getPlayerExact(arguments.get(1)); + final String key = token.substring(0, equalsPos); + final String value = token.substring(equalsPos + 1); + menuArgs.put(key, value); + } + } - } else { - if (arguments.size() >= 3) { - if (!sender.hasPermission("deluxemenus.open.others")) { - plugin.sms(sender, Messages.NO_PERMISSION); - return; - } + Player viewer; - viewer = Bukkit.getPlayerExact(arguments.get(1)); + if (viewerName != null) { + if (player && !sender.hasPermission("deluxemenus.open.others")) { + plugin.sms(sender, Messages.NO_PERMISSION); + return; + } - } else { - if (!player) { - plugin.sms(sender, Messages.MUST_SPECIFY_PLAYER); - return; - } + viewer = Bukkit.getPlayerExact(viewerName); - viewer = (Player) sender; - } + if (viewer == null) { + plugin.sms(sender, Messages.PLAYER_IS_NOT_ONLINE.message().replaceText(PLAYER_REPLACER_BUILDER.replacement(viewerName).build())); + return; } } else { @@ -104,37 +124,29 @@ public void execute(final @NotNull CommandSender sender, final @NotNull List menu = Menu.getMenuByName(arguments.get(0)); + Optional menu = Menu.getMenuByName(menuName); if (menu.isEmpty()) { - plugin.sms(sender, Messages.INVALID_MENU.message().replaceText(MENU_REPLACER_BUILDER.replacement(arguments.get(0)).build())); + plugin.sms(sender, Messages.INVALID_MENU.message().replaceText(MENU_REPLACER_BUILDER.replacement(menuName).build())); return; } - menu.get().openMenu(viewer, null, placeholder); + menu.get().openMenu(viewer, menuArgs, placeholder); } @Override @@ -147,18 +159,10 @@ public void execute(final @NotNull CommandSender sender, final @NotNull List 4) { - return null; - } - if (arguments.size() == 1) { - if (arguments.get(0).isEmpty()) { - return List.of(getName()); - } - final String firstArgument = arguments.get(0).toLowerCase(); - if (getName().startsWith(firstArgument)) { + if (firstArgument.isEmpty() || getName().startsWith(firstArgument)) { return List.of(getName()); } @@ -194,42 +198,75 @@ public void execute(final @NotNull CommandSender sender, final @NotNull List playerName.toLowerCase().startsWith(thirdArgument)) + if (!viewerConsumed && !placeholderConsumed + && !current.startsWith(PLACEHOLDER_FLAG) + && !current.equals(ARGS_MARKER)) { + viewerConsumed = true; + } else if (!placeholderConsumed && current.startsWith(PLACEHOLDER_FLAG)) { + placeholderConsumed = true; + } else if (current.equals(ARGS_MARKER)) { + argsMarkerConsumed = true; + } + } + + if (argsMarkerConsumed) { + return null; + } + + final String lastArgument = arguments.get(arguments.size() - 1); + final String lastArgumentLower = lastArgument.toLowerCase(); + + if (!viewerConsumed && !placeholderConsumed) { + // Still in the viewer slot: suggest online players, -p:, or -args: + if (lastArgumentLower.isEmpty()) { + return Stream.concat(onlinePlayerNames.stream(), Stream.of(PLACEHOLDER_FLAG, ARGS_MARKER)) + .collect(Collectors.toList()); + } + + if (lastArgumentLower.startsWith("-")) { + return Stream.of(PLACEHOLDER_FLAG, ARGS_MARKER) + .filter(option -> option.startsWith(lastArgumentLower)) .collect(Collectors.toList()); } return onlinePlayerNames.stream() - .map(playerName -> "-p:" + playerName) - .filter(playerName -> playerName.toLowerCase().startsWith(thirdArgument)) + .filter(playerName -> playerName.toLowerCase().startsWith(lastArgumentLower)) .collect(Collectors.toList()); } - if (arguments.size() == 4) { - final String thirdArgument = arguments.get(2).toLowerCase(); - final String fourthArgument = arguments.get(3).toLowerCase(); - - if (!thirdArgument.startsWith("-p:")) { - return null; + if (viewerConsumed && !placeholderConsumed) { + // Viewer already given: suggest -p: or -args: + if (lastArgumentLower.isEmpty()) { + return List.of(PLACEHOLDER_FLAG, ARGS_MARKER); } - if (fourthArgument.isEmpty()) { - return onlinePlayerNames; + if (lastArgumentLower.startsWith(PLACEHOLDER_FLAG)) { + return onlinePlayerNames.stream() + .map(playerName -> PLACEHOLDER_FLAG + playerName) + .filter(option -> option.toLowerCase().startsWith(lastArgumentLower)) + .collect(Collectors.toList()); } - return onlinePlayerNames.stream() - .filter(playerName -> playerName.toLowerCase().startsWith(fourthArgument)) + return Stream.of(PLACEHOLDER_FLAG, ARGS_MARKER) + .filter(option -> option.startsWith(lastArgumentLower)) .collect(Collectors.toList()); } + if (lastArgumentLower.isEmpty() || ARGS_MARKER.startsWith(lastArgumentLower)) { + return List.of(ARGS_MARKER); + } + return null; } }