diff --git a/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java b/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java index 013e00c..d971a9a 100644 --- a/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java +++ b/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java @@ -8,6 +8,7 @@ import org.javacord.api.event.message.MessageCreateEvent; import org.javacord.api.listener.message.MessageCreateListener; import sciwhiz12.janitor.JanitorBot; import sciwhiz12.janitor.commands.bot.ShutdownCommand; +import sciwhiz12.janitor.commands.misc.HelloCommand; import sciwhiz12.janitor.commands.misc.OKCommand; import sciwhiz12.janitor.commands.misc.PingCommand; import sciwhiz12.janitor.utils.Util; @@ -34,10 +35,10 @@ public class CommandRegistry implements MessageCreateListener { addCommand(new PingCommand(this, "ping", "Pong!")); addCommand(new PingCommand(this, "pong", "Ping!")); addCommand(new OKCommand(this)); + addCommand(new HelloCommand(this)); if (bot.getConfig().getOwnerID().isPresent()) { addCommand(new ShutdownCommand(this, bot.getConfig().getOwnerID().get())); } - } public CommandDispatcher getDispatcher() { @@ -56,15 +57,18 @@ public class CommandRegistry implements MessageCreateListener { public void onMessageCreate(MessageCreateEvent event) { String msg = event.getMessage().getContent(); if (!msg.startsWith(this.prefix)) return; + JANITOR.debug(COMMANDS, "Received message starting with valid command prefix. Author: {}, full message: {}", + Util.toString(event.getMessageAuthor().asUser().orElse(null)), msg); try { StringReader command = new StringReader(msg.substring(this.prefix.length())); ParseResults parseResults = this.dispatcher.parse(command, event); if (parseResults.getReader().canRead()) { // Parsing did not succeed, i.e. command not found // TODO: add separate code path when insufficient permissions / requires fails + JANITOR.error(COMMANDS, "Error while parsing command: {}", parseResults.getExceptions().values()); return; } - JANITOR.debug(COMMANDS, "Received command and executing. Author: {}, full message: {}", Util.toString(event.getMessageAuthor().asUser().orElse(null)), msg); + JANITOR.debug(COMMANDS, "Executing command."); dispatcher.execute(parseResults); } catch (CommandSyntaxException ex) { JANITOR.error(COMMANDS, "Error while parsing message and executing command", ex); diff --git a/src/main/java/sciwhiz12/janitor/commands/arguments/UserArgument.java b/src/main/java/sciwhiz12/janitor/commands/arguments/UserArgument.java new file mode 100644 index 0000000..d43d3bf --- /dev/null +++ b/src/main/java/sciwhiz12/janitor/commands/arguments/UserArgument.java @@ -0,0 +1,64 @@ +package sciwhiz12.janitor.commands.arguments; + +import com.google.common.collect.ImmutableList; +import com.mojang.brigadier.LiteralMessage; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import org.javacord.api.DiscordApi; +import org.javacord.api.entity.user.User; + +import java.util.Collection; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class UserArgument implements ArgumentType { + public static final SimpleCommandExceptionType UNKNOWN_USER_IDENTIFIER = new SimpleCommandExceptionType(new LiteralMessage("Unknown user identifier")); + public static final Pattern USER_IDENTIFIER_PATTERN = Pattern.compile("<@!([0-9]+)>"); + + public static UserArgument user() { + return new UserArgument(); + } + + public static IUserProvider getUser(String name, CommandContext ctx) { + return ctx.getArgument(name, IUserProvider.class); + } + + @Override + public IUserProvider parse(StringReader reader) throws CommandSyntaxException { + if (reader.peek() == '<') { // Expecting a possible user identifier + int start = reader.getCursor(); + reader.readStringUntil('>'); + Matcher matcher = USER_IDENTIFIER_PATTERN.matcher(reader.getString().substring(start, reader.getCursor())); + if (matcher.matches()) { + return new NumericalProvider(Long.parseLong(matcher.group(1))); + } + } + throw UNKNOWN_USER_IDENTIFIER.create(); + } + + @Override + public Collection getExamples() { + return ImmutableList.of("<@!607058472709652501>", "<@750291676764962816>"); + } + + public interface IUserProvider { + CompletableFuture getUsers(DiscordApi api); + } + + static class NumericalProvider implements IUserProvider { + private final long snowflakeID; + + NumericalProvider(long snowflakeID) { + this.snowflakeID = snowflakeID; + } + + @Override + public CompletableFuture getUsers(DiscordApi api) { + return api.getUserById(snowflakeID); + } + } +} diff --git a/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java b/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java new file mode 100644 index 0000000..8c3f025 --- /dev/null +++ b/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java @@ -0,0 +1,43 @@ +package sciwhiz12.janitor.commands.misc; + +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import org.javacord.api.event.message.MessageCreateEvent; +import sciwhiz12.janitor.commands.BaseCommand; +import sciwhiz12.janitor.commands.CommandRegistry; +import sciwhiz12.janitor.commands.arguments.UserArgument; +import sciwhiz12.janitor.utils.Util; + +import static sciwhiz12.janitor.Logging.JANITOR; +import static sciwhiz12.janitor.utils.CommandHelper.argument; +import static sciwhiz12.janitor.utils.CommandHelper.literal; + +public class HelloCommand extends BaseCommand { + public HelloCommand(CommandRegistry registry) { + super(registry); + } + + public LiteralArgumentBuilder getNode() { + return literal("greet") + .then( + argument("user", UserArgument.user()) + .executes(this::run) + ); + } + + int run(final CommandContext ctx) { + UserArgument.getUser("user", ctx).getUsers(ctx.getSource().getApi()) + .thenCompose(user -> + ctx.getSource() + .getMessage() + .getChannel() + .sendMessage("Hello " + user.getMentionTag() + " !") + ) + .whenCompleteAsync(Util.handle( + success -> JANITOR.debug("Sent greeting message to {}", Util.toString(ctx.getSource().getMessageAuthor())), + err -> JANITOR.error("Error while sending greeting message to {}", Util.toString(ctx.getSource().getMessageAuthor())) + ) + ); + return 1; + } +} diff --git a/src/main/java/sciwhiz12/janitor/utils/CommandHelper.java b/src/main/java/sciwhiz12/janitor/utils/CommandHelper.java index c795da6..e2bd524 100644 --- a/src/main/java/sciwhiz12/janitor/utils/CommandHelper.java +++ b/src/main/java/sciwhiz12/janitor/utils/CommandHelper.java @@ -1,10 +1,16 @@ package sciwhiz12.janitor.utils; +import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; import org.javacord.api.event.message.MessageCreateEvent; public class CommandHelper { public static LiteralArgumentBuilder literal(String command) { return LiteralArgumentBuilder.literal(command); } + + public static RequiredArgumentBuilder argument(String command, ArgumentType argument) { + return RequiredArgumentBuilder.argument(command, argument); + } }