Skip to content

Add annotation support for buttons #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
4 changes: 4 additions & 0 deletions src/main/java/uk/co/nyvil/Bot.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,6 +47,8 @@ public class Bot {
@Getter
private CommandHandler commandHandler;
@Getter
private ButtonHandler buttonhandler;
@Getter
private DatabaseConnection databaseConnection;
@Getter
private BotConnection botConnection;
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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;
import uk.co.nyvil.Bot;
import uk.co.nyvil.bot.buttons.status.ButtonClickInfo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;


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;

String componentID = event.getComponentId();
Map<String, ButtonMethods> 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();

try {
method.invoke(buttonMethod.getObj(), new ButtonClickInfo(event, event.getMember(), event.getTextChannel(), componentID));
} catch (IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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<String, ButtonMethods> 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();

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()) {
buttonMap.put(id, new ButtonMethods(cls, method));
} else {
System.err.println("No declared buttons found in " + cls.getName() + ".");
}
});
}
}
}
16 changes: 16 additions & 0 deletions src/main/java/uk/co/nyvil/bot/buttons/manager/ButtonMethods.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
23 changes: 23 additions & 0 deletions src/main/java/uk/co/nyvil/bot/buttons/status/ButtonClickInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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;

@Getter
@Setter
public class ButtonClickInfo {
private final ButtonClickEvent event;
private final Member clicker;
private final TextChannel textChannel;
private final String id;

public ButtonClickInfo(ButtonClickEvent event, Member clicker, TextChannel textChannel, String id) {
this.event = event;
this.clicker = clicker;
this.textChannel = textChannel;
this.id = id;
}
}
19 changes: 16 additions & 3 deletions src/main/java/uk/co/nyvil/bot/commands/commands/PingCommand.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down