diff --git a/src/main/java/dev/marcospaulo/canalhandia/AiProfile.java b/src/main/java/dev/marcospaulo/canalhandia/AiProfile.java index 4ff3906..07f6569 100644 --- a/src/main/java/dev/marcospaulo/canalhandia/AiProfile.java +++ b/src/main/java/dev/marcospaulo/canalhandia/AiProfile.java @@ -22,4 +22,17 @@ enum AiProfile { } return PRECISO; } + + /** True if {@code key} names a profile. Use before {@link #byKey} to tell a + * real key from the {@code PRECISO} fallback, so {@code /ia perfil blah} + * can be rejected (or fall through to a question) rather than silently + * switching to PRECISO. */ + static boolean isValid(String key) { + for (AiProfile profile : values()) { + if (profile.name().equalsIgnoreCase(key)) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/src/main/java/dev/marcospaulo/canalhandia/CanalhandiaCommand.java b/src/main/java/dev/marcospaulo/canalhandia/CanalhandiaCommand.java index c43ddff..d09255c 100644 --- a/src/main/java/dev/marcospaulo/canalhandia/CanalhandiaCommand.java +++ b/src/main/java/dev/marcospaulo/canalhandia/CanalhandiaCommand.java @@ -759,7 +759,12 @@ final class CanalhandiaCommand implements CommandExecutor, TabCompleter { * {@code lp user permission set canalhandia.ia true}. */ private boolean ia(CommandSender sender, String[] args, boolean isPrivate) { - if (!sender.hasPermission("canalhandia.ia")) { + // /ia and /iap are separate gates so LuckPerms can grant them + // independently — an operator can let someone ask privately without + // letting them spam public chat, or vice-versa. Both default to op, + // matching the "operator + LuckPerms-permitted only" rule. + String perm = isPrivate ? "canalhandia.ia.privado" : "canalhandia.ia"; + if (!sender.hasPermission(perm)) { return denied(sender); } if (!plugin.settings().moduleEnabled(Module.IA)) { @@ -770,18 +775,27 @@ final class CanalhandiaCommand implements CommandExecutor, TabCompleter { Msg.error(sender, "Só jogadores podem usar /ia."); return true; } - // Subcommands come before the question. Tradeoff: a question that - // literally starts with "perfil", "corrigir" or "feedback" is hijacked - // — e.g. "/ia perfil do servidor" runs /ia perfil with no profile name - // and shows usage instead of asking. Acceptable on a small server, - // where the operator commands matter more than the edge case. + // Subcommands come before the question. They only hijack when the + // second token is one they would actually act on, so a real question + // like "/ia perfil do servidor" or "/ia feedback do mapa?" falls + // through and is asked. "corrigir" stays greedy — a correction always + // reads the rest of the line, and "/ia corrigir ..." is never a natural + // question. if (args.length > 0) { - switch (args[0].toLowerCase(Locale.ROOT)) { - case "perfil" -> { iaProfile(sender, args); return true; } - case "corrigir" -> { iaCorrect(sender, args); return true; } - case "feedback" -> { iaFeedback(sender, args); return true; } - default -> { /* fall through: treat all args as the question */ } + String sub = args[0].toLowerCase(Locale.ROOT); + if (sub.equals("perfil") && (args.length == 1 || AiProfile.isValid(args[1]))) { + iaProfile(sender, args); + return true; } + if (sub.equals("corrigir")) { + iaCorrect(sender, args); + return true; + } + if (sub.equals("feedback") && args.length >= 2 && args[1].equalsIgnoreCase("ruim")) { + iaFeedback(sender, args); + return true; + } + // default: treat all args as the question } if (args.length == 0) { Msg.error(sender, isPrivate ? "Uso: /iap " : "Uso: /ia "); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 916a7f8..056cfdd 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -90,8 +90,8 @@ permissions: description: Permite usar /ia. Padrão op; o LuckPerms pode conceder a outros. default: op canalhandia.ia.privado: - description: Permite perguntar em privado com /iap. - default: true + description: Permite perguntar em privado com /iap. Padrão op; o LuckPerms pode conceder a outros. + default: op canalhandia.ia.corrigir: description: Permite registrar correções para as respostas da IA. default: op