From 22dce76cddfc21d6dd04c0c3071632a8df68abee Mon Sep 17 00:00:00 2001 From: Technosword <33706033+Technosword@users.noreply.github.com> Date: Sun, 23 Jan 2022 00:05:37 -0500 Subject: [PATCH 1/4] Initial Commit working on buttons. Untested and see todos --- README.md | 1 + .../bot/buttons/manager/ButtonAnnotation.java | 10 ++++++ .../buttons/manager/ButtonClickHandler.java | 17 ++++++++++ .../bot/buttons/manager/ButtonHandler.java | 33 +++++++++++++++++++ .../bot/buttons/status/ButtonClickInfo.java | 26 +++++++++++++++ .../bot/commands/commands/PingCommand.java | 19 +++++++++-- 6 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonAnnotation.java create mode 100644 src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java create mode 100644 src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java create mode 100644 src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java diff --git a/README.md b/README.md index c9a4db2..95f3483 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ If not you can report it [here](https://github.com/Nyvil/Nyjava/issues) # Author(s) * **[Alexandros(@Nyvil)](https://github.com/Nyvil)** - initial work +* **[@Technosword](https://github.com/Technosword)** - buttons # License This project is licensed under the Apache 2.0 License - see the [LICENSE](https://github.com/Nyvil/Nyjava/blob/stable/LICENSE) file for details. diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonAnnotation.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonAnnotation.java new file mode 100644 index 0000000..bf9f46d --- /dev/null +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonAnnotation.java @@ -0,0 +1,10 @@ +package uk.co.nyvil.bot.buttons.manager; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(value = RetentionPolicy.RUNTIME) +public @interface ButtonAnnotation { + + String id(); +} diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java new file mode 100644 index 0000000..d7c7c04 --- /dev/null +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java @@ -0,0 +1,17 @@ +package uk.co.nyvil.bot.buttons.manager; + +import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; + +public class ButtonClickHandler extends ListenerAdapter { + + @Override + public void onButtonClick(@NotNull ButtonClickEvent event) { + if(event.getGuild() == null) return; + if(event.getUser().isBot()) return; + if(event.getMember() == null) return; + //TODO: Get the method from a registry and run it + + } +} diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java new file mode 100644 index 0000000..cbe02e5 --- /dev/null +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java @@ -0,0 +1,33 @@ +package uk.co.nyvil.bot.buttons.manager; + +import uk.co.nyvil.bot.buttons.status.ButtonClickInfo; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Comparator; + +public class ButtonHandler { + private void registerButtons(Object... objs) { + for (Object obj : objs) { + final Class cls = obj.getClass(); + + Arrays.stream(cls.getDeclaredMethods()) + .filter(method -> + (method.getModifiers() & (Modifier.PROTECTED | Modifier.PRIVATE)) == 0 + && method.isAnnotationPresent(ButtonAnnotation.class) + && method.getParameterCount() == 1 + && method.getParameterTypes()[0] == ButtonClickInfo.class + ) + .sorted(Comparator.comparing(Method::getName)) + .forEach(method -> { + final String id = method.getAnnotation(ButtonAnnotation.class).id(); + + if (!id.isEmpty()) { + // we want to register it uh somewhere, maybe put the id and class/method in a + //TODO: Create a registry + } + }); + } + } +} diff --git a/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java b/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java new file mode 100644 index 0000000..2210747 --- /dev/null +++ b/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java @@ -0,0 +1,26 @@ +package uk.co.nyvil.bot.buttons.status; + +import lombok.Getter; +import lombok.Setter; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; +import uk.co.nyvil.bot.buttons.manager.ButtonAnnotation; + +@Getter +@Setter +public class ButtonClickInfo { + private final ButtonClickEvent event; + private final Member clicker; + private final TextChannel textChannel; + private final ButtonAnnotation annotation; + private final String id; + + public ButtonClickInfo(ButtonClickEvent event, Member clicker, TextChannel textChannel, ButtonAnnotation annotation, String id) { + this.event = event; + this.clicker = clicker; + this.textChannel = textChannel; + this.annotation = annotation; + this.id = id; + } +} diff --git a/src/main/java/uk/co/nyvil/bot/commands/commands/PingCommand.java b/src/main/java/uk/co/nyvil/bot/commands/commands/PingCommand.java index 75277c9..2ed0e1d 100644 --- a/src/main/java/uk/co/nyvil/bot/commands/commands/PingCommand.java +++ b/src/main/java/uk/co/nyvil/bot/commands/commands/PingCommand.java @@ -1,20 +1,33 @@ package uk.co.nyvil.bot.commands.commands; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.interactions.components.Button; import uk.co.nyvil.bot.BotConnection; +import uk.co.nyvil.bot.buttons.manager.ButtonAnnotation; +import uk.co.nyvil.bot.buttons.status.ButtonClickInfo; import uk.co.nyvil.bot.commands.manager.*; import uk.co.nyvil.bot.commands.status.SlashCommandExecutionInfo; import uk.co.nyvil.utils.MessageUtils; +import java.util.Objects; + public class PingCommand implements SlashCommand { @Override @SlashCommandAnnotation(name = "ping") public void execute(SlashCommandExecutionInfo info) { final long time = System.currentTimeMillis(); - info.getEvent().replyEmbeds(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: measuring...").build()).queue(message -> { - message.editOriginalEmbeds(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: " + (System.currentTimeMillis() - time) + "ms").build()).queue(); - }); + info.getEvent().replyEmbeds(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: measuring...").build()) + .addActionRow(Button.primary("ping", "Refresh")) + .queue(message -> message.editOriginalEmbeds(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: " + (System.currentTimeMillis() - time) + "ms").build()).queue()); + } + + @ButtonAnnotation(id ="ping") + public void onButtonClick(ButtonClickInfo info) { + final long time = System.currentTimeMillis(); + Objects.requireNonNull(info.getEvent().getMessage()).editMessage(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: measuring...").build()) + .queue(message -> message.editMessage(MessageUtils.createInfoEmbed("Current Gateaway latency: " + BotConnection.getJda().getGatewayPing() + "ms\nResponse time: " + (System.currentTimeMillis() - time) + "ms").build()).queue()); + info.getEvent().reply("Updated the ping!").setEphemeral(true).queue(); } @Override From ac6e966f3c411888d868447fd8aa946a5d5d45c6 Mon Sep 17 00:00:00 2001 From: Technosword <33706033+Technosword@users.noreply.github.com> Date: Sun, 23 Jan 2022 23:18:01 -0500 Subject: [PATCH 2/4] Added a way to store methods/classes: ButtonMethods.java. Continued working on button support. Check pretty much final todo until completion/testing --- src/main/java/uk/co/nyvil/Bot.java | 4 ++++ .../buttons/manager/ButtonClickHandler.java | 9 ++++++++- .../bot/buttons/manager/ButtonHandler.java | 18 ++++++++++++++++-- .../bot/buttons/manager/ButtonMethods.java | 16 ++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonMethods.java diff --git a/src/main/java/uk/co/nyvil/Bot.java b/src/main/java/uk/co/nyvil/Bot.java index 6bed6dc..fa78c3b 100644 --- a/src/main/java/uk/co/nyvil/Bot.java +++ b/src/main/java/uk/co/nyvil/Bot.java @@ -11,6 +11,7 @@ import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.*; import uk.co.nyvil.bot.BotConnection; +import uk.co.nyvil.bot.buttons.manager.ButtonHandler; import uk.co.nyvil.bot.commands.manager.CommandHandler; import uk.co.nyvil.database.DatabaseConnection; import uk.co.nyvil.database.utils.DatabaseUtils; @@ -46,6 +47,8 @@ public class Bot { @Getter private CommandHandler commandHandler; @Getter + private ButtonHandler buttonhandler; + @Getter private DatabaseConnection databaseConnection; @Getter private BotConnection botConnection; @@ -83,6 +86,7 @@ private void start() { FileUtils.setToken(token); botConnection = new BotConnection(); commandHandler = new CommandHandler(); + buttonhandler = new ButtonHandler(); if (getInstance().dbStart) { databaseConnection = new DatabaseConnection(); } else { diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java index d7c7c04..748a88d 100644 --- a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java @@ -3,6 +3,9 @@ import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.jetbrains.annotations.NotNull; +import uk.co.nyvil.Bot; + +import java.util.Objects; public class ButtonClickHandler extends ListenerAdapter { @@ -11,7 +14,11 @@ public void onButtonClick(@NotNull ButtonClickEvent event) { if(event.getGuild() == null) return; if(event.getUser().isBot()) return; if(event.getMember() == null) return; - //TODO: Get the method from a registry and run it + + + if (Bot.getInstance().getButtonhandler().getButtonMap().containsKey(Objects.requireNonNull(event.getButton()).getId())) { +//TODO: Finish this, computer crashed so I lost a good bit of code + } } } diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java index cbe02e5..4a10038 100644 --- a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java @@ -1,13 +1,26 @@ package uk.co.nyvil.bot.buttons.manager; +import lombok.Getter; import uk.co.nyvil.bot.buttons.status.ButtonClickInfo; +import uk.co.nyvil.bot.commands.commands.PingCommand; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; public class ButtonHandler { + @Getter + public final Map buttonMap = new HashMap<>(); + + /** + * Declare all classes that contain buttons in this class + */ + public ButtonHandler(){ + registerButtons(PingCommand.class); + } private void registerButtons(Object... objs) { for (Object obj : objs) { final Class cls = obj.getClass(); @@ -24,8 +37,9 @@ private void registerButtons(Object... objs) { final String id = method.getAnnotation(ButtonAnnotation.class).id(); if (!id.isEmpty()) { - // we want to register it uh somewhere, maybe put the id and class/method in a - //TODO: Create a registry + buttonMap.put(id, new ButtonMethods(cls, method)); + } else { + System.err.println("No declared buttons found in " + cls.getName() + "."); } }); } diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonMethods.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonMethods.java new file mode 100644 index 0000000..04a5a6f --- /dev/null +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonMethods.java @@ -0,0 +1,16 @@ +package uk.co.nyvil.bot.buttons.manager; + +import lombok.Getter; + +import java.lang.reflect.Method; + +@Getter +public class ButtonMethods { + private final Object obj; + private final Method method; + + ButtonMethods(Object obj, Method method) { + this.obj = obj; + this.method = method; + } +} From c4cbdc5413158121dac11eb0f64ead3386957474 Mon Sep 17 00:00:00 2001 From: Technosword <33706033+Technosword@users.noreply.github.com> Date: Tue, 25 Jan 2022 17:19:19 -0500 Subject: [PATCH 3/4] Finished button support. TODO: Documentation --- .../buttons/manager/ButtonClickHandler.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java index 748a88d..a144d40 100644 --- a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java @@ -5,7 +5,10 @@ import org.jetbrains.annotations.NotNull; import uk.co.nyvil.Bot; -import java.util.Objects; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + public class ButtonClickHandler extends ListenerAdapter { @@ -15,10 +18,17 @@ public void onButtonClick(@NotNull ButtonClickEvent event) { if(event.getUser().isBot()) return; if(event.getMember() == null) return; + String componentID = event.getComponentId(); + Map buttonMap = Bot.getInstance().getButtonhandler().getButtonMap(); + if (Bot.getInstance().getButtonhandler().getButtonMap().containsKey(componentID)) { + ButtonMethods buttonMethod = Bot.getInstance().getButtonhandler().getButtonMap().get(componentID); + final Method method = buttonMethod.getMethod(); - if (Bot.getInstance().getButtonhandler().getButtonMap().containsKey(Objects.requireNonNull(event.getButton()).getId())) { -//TODO: Finish this, computer crashed so I lost a good bit of code + try { + method.invoke(buttonMethod.getObj(), event); + } catch (IllegalAccessException | InvocationTargetException ex) { + ex.printStackTrace(); + } } - } } From 04e69e471645daee42b7a875b1a198c7e0d21d5f Mon Sep 17 00:00:00 2001 From: Technosword <33706033+Technosword@users.noreply.github.com> Date: Tue, 25 Jan 2022 19:59:45 -0500 Subject: [PATCH 4/4] Button click provides the method with buttonclickinfo instead of the event. --- .../uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java | 3 ++- .../java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java index a144d40..b3cacbd 100644 --- a/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java +++ b/src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonClickHandler.java @@ -4,6 +4,7 @@ import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.jetbrains.annotations.NotNull; import uk.co.nyvil.Bot; +import uk.co.nyvil.bot.buttons.status.ButtonClickInfo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -25,7 +26,7 @@ public void onButtonClick(@NotNull ButtonClickEvent event) { final Method method = buttonMethod.getMethod(); try { - method.invoke(buttonMethod.getObj(), event); + method.invoke(buttonMethod.getObj(), new ButtonClickInfo(event, event.getMember(), event.getTextChannel(), componentID)); } catch (IllegalAccessException | InvocationTargetException ex) { ex.printStackTrace(); } diff --git a/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java b/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java index 2210747..1afe790 100644 --- a/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java +++ b/src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java @@ -5,7 +5,6 @@ import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; -import uk.co.nyvil.bot.buttons.manager.ButtonAnnotation; @Getter @Setter @@ -13,14 +12,12 @@ public class ButtonClickInfo { private final ButtonClickEvent event; private final Member clicker; private final TextChannel textChannel; - private final ButtonAnnotation annotation; private final String id; - public ButtonClickInfo(ButtonClickEvent event, Member clicker, TextChannel textChannel, ButtonAnnotation annotation, String id) { + public ButtonClickInfo(ButtonClickEvent event, Member clicker, TextChannel textChannel, String id) { this.event = event; this.clicker = clicker; this.textChannel = textChannel; - this.annotation = annotation; this.id = id; } }