summaryrefslogtreecommitdiff
path: root/src/main/java/net
diff options
context:
space:
mode:
authorTyler Murphy <tylermurphy534@gmail.com>2022-08-24 15:59:11 -0400
committerTyler Murphy <tylermurphy534@gmail.com>2022-08-24 15:59:11 -0400
commit14e9087dfab387495f32c5a1816df7fc9f031e47 (patch)
treeeec8da6c3b2d93044856a83cae1fdad29a36d9c1 /src/main/java/net
parentv6 (diff)
downloadken-14e9087dfab387495f32c5a1816df7fc9f031e47.tar.gz
ken-14e9087dfab387495f32c5a1816df7fc9f031e47.tar.bz2
ken-14e9087dfab387495f32c5a1816df7fc9f031e47.zip
v6
Diffstat (limited to 'src/main/java/net')
-rw-r--r--src/main/java/net/tylermurphy/ken/Ken.java20
-rw-r--r--src/main/java/net/tylermurphy/ken/command/Container.java49
-rw-r--r--src/main/java/net/tylermurphy/ken/command/Register.java96
-rw-r--r--src/main/java/net/tylermurphy/ken/command/Responder.java245
-rw-r--r--src/main/java/net/tylermurphy/ken/command/Response.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/fun/Dice.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/fun/Eject.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/AddRole.java44
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/AddRolesPage.java40
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/AddSelfRole.java13
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/DeleteRole.java53
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/DeleteRolesPage.java (renamed from src/main/java/net/tylermurphy/ken/command/main/DeleteSelfRole.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/Help.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/Purge.java6
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/ForceSkip.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Join.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Leave.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Loop.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/LoopQueue.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/NowPlaying.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Pause.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Play.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Queue.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Remove.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Resume.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Skip.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/music/Stop.java2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Danbooru.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/E621.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Gelbooru.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Hentai.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Konachan.java5
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Rule34.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/Yandere.java4
-rw-r--r--src/main/java/net/tylermurphy/ken/command/nsfw/nHentai.java6
-rw-r--r--src/main/java/net/tylermurphy/ken/database/SelfRoleTable.java39
-rw-r--r--src/main/java/net/tylermurphy/ken/event/Responder.java234
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/ButtonCallback.java (renamed from src/main/java/net/tylermurphy/ken/util/ButtonCallback.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Command.java (renamed from src/main/java/net/tylermurphy/ken/util/Command.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Option.java (renamed from src/main/java/net/tylermurphy/ken/util/Option.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Options.java (renamed from src/main/java/net/tylermurphy/ken/util/Options.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Requirement.java (renamed from src/main/java/net/tylermurphy/ken/util/Requirement.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Selection.java (renamed from src/main/java/net/tylermurphy/ken/util/Selection.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/event/annotation/Selections.java (renamed from src/main/java/net/tylermurphy/ken/util/Selections.java)2
45 files changed, 557 insertions, 383 deletions
diff --git a/src/main/java/net/tylermurphy/ken/Ken.java b/src/main/java/net/tylermurphy/ken/Ken.java
index 97df266..b9b7a97 100644
--- a/src/main/java/net/tylermurphy/ken/Ken.java
+++ b/src/main/java/net/tylermurphy/ken/Ken.java
@@ -7,12 +7,10 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Activity;
-import net.dv8tion.jda.api.entities.TextChannel;
-import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
-import net.tylermurphy.ken.command.Responder;
+import net.tylermurphy.ken.event.Responder;
import net.tylermurphy.ken.database.Database;
import net.tylermurphy.ken.music.PlayerManager;
import org.jetbrains.annotations.NotNull;
@@ -22,7 +20,6 @@ import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.io.File;
import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
public class Ken {
@@ -52,12 +49,7 @@ public class Ken {
throw new RuntimeException("Unable to Initialize JDA");
}
this.responder = new Responder(api);
- try{
- responder.registerCommands();
- } catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
- log.error(e.getMessage());
- throw new RuntimeException("Unable to register commands");
- }
+ this.responder.registerCommands();
this.addEventListener(responder);
this.playerManager = new PlayerManager();
try {
@@ -108,14 +100,6 @@ public class Ken {
return builder;
}
- public TextChannel getTextChannel(long id) {
- return api.getTextChannelById(id);
- }
-
- public VoiceChannel getVoiceChannel(long id) {
- return api.getVoiceChannelById(id);
- }
-
public void addEventListener(ListenerAdapter listener){
api.addEventListener(listener);
}
diff --git a/src/main/java/net/tylermurphy/ken/command/Container.java b/src/main/java/net/tylermurphy/ken/command/Container.java
deleted file mode 100644
index 55e05ed..0000000
--- a/src/main/java/net/tylermurphy/ken/command/Container.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.tylermurphy.ken.command;
-
-import net.dv8tion.jda.api.Permission;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-public class Container {
-
- private final Method method;
- private final Object handle;
-
- private Method buttonCallback;
- private Permission permission;
-
- public Container(Method method) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
- this.method = method;
- this.handle = method.getDeclaringClass().getConstructor().newInstance();
- }
-
- public Container setButtonCallback(Method method){
- this.buttonCallback = method;
- return this;
- }
-
- public Container setPermission(Permission permission){
- this.permission = permission;
- return this;
- }
-
- public Method getMethod(){
- return method;
- }
-
- public Object getHandle(){
- return handle;
- }
-
- public Method getButtonCallback(){
- return buttonCallback;
- }
-
- public Permission getPermission(){
- return permission;
- }
-
-
-
-}
diff --git a/src/main/java/net/tylermurphy/ken/command/Register.java b/src/main/java/net/tylermurphy/ken/command/Register.java
new file mode 100644
index 0000000..24c7860
--- /dev/null
+++ b/src/main/java/net/tylermurphy/ken/command/Register.java
@@ -0,0 +1,96 @@
+package net.tylermurphy.ken.command;
+
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.interactions.commands.build.Commands;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
+import net.tylermurphy.ken.event.annotation.*;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+public class Register {
+
+ private final Map<String, Object> HANDLES;
+ private final Map<String, Method> COMMAND_CALLBACKS;
+ private final Map<String, Method> BUTTON_CALLBACKS;
+ private final Map<String, Permission> PERMISSIONS;
+
+ private final JDA api;
+
+ public Register(JDA api){
+ HANDLES = new HashMap<>();
+ COMMAND_CALLBACKS = new HashMap<>();
+ BUTTON_CALLBACKS = new HashMap<>();
+ PERMISSIONS = new HashMap<>();
+
+ this.api = api;
+ }
+
+ public void register(Object handle) {
+ if(HANDLES.containsKey(handle.getClass().getName())) return;
+ List<Method> commands = Arrays.stream(handle.getClass().getMethods()).filter(method -> method.isAnnotationPresent(Command.class)).toList();
+ List<Method> buttons = Arrays.stream(handle.getClass().getMethods()).filter(method -> method.isAnnotationPresent(ButtonCallback.class)).toList();
+ if(commands.isEmpty() && buttons.isEmpty()) return;
+ HANDLES.put(handle.getClass().getName(), handle);
+ commands.forEach(this::registerCommand);
+ buttons.forEach(this::registerButton);
+ }
+
+ private void registerCommand(Method method){
+ Command command = method.getAnnotation(Command.class);
+ if(COMMAND_CALLBACKS.containsKey(command.name())) return;
+ COMMAND_CALLBACKS.put(command.name(), method);
+ if (method.isAnnotationPresent(Requirement.class)){
+ PERMISSIONS.put(command.name(), method.getAnnotation(Requirement.class).value());
+ }
+ SlashCommandData data = Commands.slash(command.name(), command.description());
+ if(method.isAnnotationPresent(Options.class)) {
+ Option[] options = method.getAnnotation(Options.class).value();
+ for(Option option : options){
+ data = data.addOption(option.type(), option.name(), option.description(), option.required());
+ }
+ } else if (method.isAnnotationPresent(Option.class)) {
+ Option option = method.getAnnotation(Option.class);
+ data = data.addOption(option.type(), option.name(), option.description(), option.required());
+ }
+ if(method.isAnnotationPresent(Selections.class)){
+ Selection[] selections = method.getAnnotation(Selections.class).value();
+ for(Selection selection : selections){
+ OptionData optionData = new OptionData(selection.type(), selection.name(), selection.description(), selection.required());
+ Arrays.stream(selection.choices()).forEach(choice -> optionData.addChoice(choice, choice.toLowerCase(Locale.ROOT)));
+ data.addOptions(optionData);
+ }
+ } else if(method.isAnnotationPresent(Selection.class)){
+ Selection selection = method.getAnnotation(Selection.class);
+ OptionData optionData = new OptionData(selection.type(), selection.name(), selection.description(), selection.required());
+ Arrays.stream(selection.choices()).forEach(choice -> optionData.addChoice(choice, choice.toLowerCase(Locale.ROOT)));
+ data.addOptions(optionData);
+ }
+ api.upsertCommand(data).queue();
+ }
+
+ private void registerButton(Method method){
+ ButtonCallback callback = method.getAnnotation(ButtonCallback.class);
+ if(BUTTON_CALLBACKS.containsKey(callback.name())) return;
+ BUTTON_CALLBACKS.put(callback.name(), method);
+ }
+
+ public Method getCommand(String name){
+ return COMMAND_CALLBACKS.get(name);
+ }
+
+ public Method getButtonCallback(String name){
+ return BUTTON_CALLBACKS.get(name);
+ }
+
+ public Permission getPermission(String name){
+ return PERMISSIONS.get(name);
+ }
+
+ public Object getHandle(String name){
+ return HANDLES.get(name);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/ken/command/Responder.java b/src/main/java/net/tylermurphy/ken/command/Responder.java
deleted file mode 100644
index 21ed9ad..0000000
--- a/src/main/java/net/tylermurphy/ken/command/Responder.java
+++ /dev/null
@@ -1,245 +0,0 @@
-package net.tylermurphy.ken.command;
-
-import net.dv8tion.jda.api.EmbedBuilder;
-import net.dv8tion.jda.api.JDA;
-import net.dv8tion.jda.api.entities.Guild;
-import net.dv8tion.jda.api.entities.GuildMessageChannel;
-import net.dv8tion.jda.api.entities.Member;
-import net.dv8tion.jda.api.entities.Message;
-import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
-import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
-import net.dv8tion.jda.api.hooks.ListenerAdapter;
-import net.dv8tion.jda.api.interactions.commands.build.Commands;
-import net.dv8tion.jda.api.interactions.commands.build.OptionData;
-import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
-import net.dv8tion.jda.api.interactions.components.buttons.Button;
-import net.dv8tion.jda.api.requests.restaction.WebhookMessageCreateAction;
-import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
-import net.dv8tion.jda.api.utils.FileUpload;
-import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.*;
-import org.reflections.Reflections;
-import org.reflections.scanners.MethodAnnotationsScanner;
-
-import java.awt.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.*;
-import java.util.List;
-
-public class Responder extends ListenerAdapter {
-
- private final Map<String, Container> register;
- private final JDA api;
-
- public Responder(JDA api) {
- this.register = new HashMap<>();
- this.api = api;
- }
-
- public void registerCommands() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
-
- // Reset register
- register.clear();
-
- // Get all Methods that use the @Command annotation
- for (Method method : new Reflections("net.tylermurphy.ken.command", new MethodAnnotationsScanner()).getMethodsAnnotatedWith(Command.class)) {
- if(method.getReturnType() != Response.class) continue;
- // Register Main Command Information If Not Already Registered;
- Command command = method.getAnnotation(Command.class);
- if (register.containsKey(command.name())) continue;
- // Create Command Container
- Container container = new Container(method);
- // Check For Permissions
- if (method.isAnnotationPresent(Requirement.class))
- container.setPermission(method.getAnnotation(Requirement.class).value());
- // Add Command To Register
- register.put(command.name(), container);
- // Create Slash Command Data
- SlashCommandData data = Commands.slash(command.name(), command.description());
- // Add Options to Slash Command Data if @Option is used
- if(method.isAnnotationPresent(Options.class)) {
- Option[] options = method.getAnnotation(Options.class).value();
- for(Option option : options){
- data = data.addOption(option.type(), option.name(), option.description(), option.required());
- }
- } else if (method.isAnnotationPresent(Option.class)) {
- Option option = method.getAnnotation(Option.class);
- data = data.addOption(option.type(), option.name(), option.description(), option.required());
- }
- if(method.isAnnotationPresent(Selections.class)){
- Selection[] selections = method.getAnnotation(Selections.class).value();
- for(Selection selection : selections){
- OptionData optionData = new OptionData(selection.type(), selection.name(), selection.description(), selection.required());
- Arrays.stream(selection.choices()).forEach(choice -> optionData.addChoice(choice, choice.toLowerCase(Locale.ROOT)));
- data.addOptions(optionData);
- }
- } else if(method.isAnnotationPresent(Selection.class)){
- Selection selection = method.getAnnotation(Selection.class);
- OptionData optionData = new OptionData(selection.type(), selection.name(), selection.description(), selection.required());
- Arrays.stream(selection.choices()).forEach(choice -> optionData.addChoice(choice, choice.toLowerCase(Locale.ROOT)));
- data.addOptions(optionData);
- }
- api.upsertCommand(data).queue();
- }
-
- // Get all Methods that use the @ButtonCallback annotation
- for (Method method : new Reflections("net.tylermurphy.ken.command", new MethodAnnotationsScanner()).getMethodsAnnotatedWith(ButtonCallback.class)) {
- if(method.getReturnType() != Response.class) continue;
- ButtonCallback callback = method.getAnnotation(ButtonCallback.class);
- if(!register.containsKey(callback.name())) continue;
- Container container = register.get(callback.name());
- container.setButtonCallback(method);
- register.put(callback.name(), container);
- }
- }
-
- public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
-
- // Make sure the Bot can Talk
- if(!event.getChannel().canTalk()) return;
-
- // Bots are not allowed to use commands
- if (event.getMember() == null || event.getUser().isBot()) return;
-
- // Get Command Information From Invoke
- final String invoke = event.getName().toLowerCase(Locale.ROOT);
- if(!register.containsKey(invoke)) return;
- Container container = register.get(invoke);
- Method method = container.getMethod();
-
- // Check Permissions
- if(!event.getMember().hasPermission(container.getPermission())) {
- EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
- .appendDescription(":x: **Invalid Permissions**\n")
- .appendDescription("You require the "+ container.getPermission().toString()+" permission to use this command.");
- event.getHook().sendMessageEmbeds(builder.build()).queue();
- return;
- }
-
- // Get slash command options if there are any
- List<Object> args = new ArrayList<>();
- event.getOptions().forEach(option -> {
- switch (option.getType()){
- case STRING: args.add(option.getAsString()); break;
- case INTEGER: args.add(option.getAsInt()); break;
- case BOOLEAN: args.add(option.getAsBoolean()); break;
- case USER: args.add(option.getAsMember()); break;
- case CHANNEL: args.add(option.getAsChannel()); break;
- case ROLE: args.add(option.getAsRole()); break;
- case MENTIONABLE: args.add(option.getAsMentionable()); break;
- default: break;
- }
- });
-
- // Get parameters to send to Method
- Object[] parameters = new Object[method.getParameterTypes().length];
- Class<?>[] types = method.getParameterTypes();
- for(int i = 0; i < types.length; i++){
- if(types[i] == Member.class){
- parameters[i] = event.getMember();
- } else if(types[i] == GuildMessageChannel.class){
- parameters[i] = event.getGuildChannel();
- } else if(types[i] == Guild.class) {
- parameters[i] = event.getGuild();
- } else if(types[i] == List.class) {
- parameters[i] = args;
- } else {
- parameters[i] = null;
- }
- }
-
- // Invoke Method and Respond to User
- try {
- Object temp = method.invoke(container.getHandle(), parameters);
- Response response = (Response)temp;
- if(response.error()) {
- EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
- .setColor(Color.RED)
- .setDescription(response.getMessage());
- event.replyEmbeds(builder.build()).setEphemeral(true).queue();
- } else {
- ReplyCallbackAction message;
- if(response.hasEmbed()) {
- message = event.replyEmbeds(response.getEmbeds());
- } else {
- message = event.reply(response.getMessage());
- }
- if(response.hasButtons()) message = message.addActionRow(response.getButtons());
- if(response.hasFile()) message = message.addFiles(FileUpload.fromData(response.getFile()));
- message.queue();
- }
- } catch (Exception e) {
- EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
- .setColor(Color.RED)
- .setTitle(":x: **Error**")
- .setDescription(e.getCause().getMessage());
- event.replyEmbeds(builder.build()).setEphemeral(true).queue();
- }
- }
-
- public void onButtonInteraction(ButtonInteractionEvent event) {
-
- // Make sure the Bot can Talk
- if(!event.getChannel().canTalk()) return;
- // Bots are not allowed to use commands
- if (event.getMember() == null || event.getUser().isBot()) return;
-
- // Get Command Information From Invoke
- final String invoke = event.getComponentId().toLowerCase(Locale.ROOT).split("_")[0];
- if(!register.containsKey(invoke)) return;
- Container container = register.get(invoke);
- Method method = container.getButtonCallback();
-
- // Defer Reply
- event.deferEdit().queue();
-
- // Get parameters to send to Method
- Object[] parameters = new Object[method.getParameterTypes().length];
- Class<?>[] types = method.getParameterTypes();
- for(int i = 0; i < types.length; i++){
- if(types[i] == Member.class){
- parameters[i] = event.getMember();
- } else if(types[i] == GuildMessageChannel.class){
- parameters[i] = event.getGuildChannel();
- } else if(types[i] == Guild.class) {
- parameters[i] = event.getGuild();
- } else if(types[i] == Button.class) {
- parameters[i] = event.getButton();
- } else if(types[i] == Message.class) {
- parameters[i] = event.getMessage();
- } else if(types[i] == String.class) {
- parameters[i] = event.getComponentId().substring(invoke.length()+1);
- } else {
- parameters[i] = null;
- }
- }
-
- // Invoke Method and Respond to User
- try {
- Object temp = method.invoke(container.getHandle(), parameters);
- Response response = (Response) temp;
- if(response.error()) {
- EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
- .setColor(Color.RED)
- .setTitle(":x: **Error**")
- .setDescription(response.getMessage());
- event.getHook().sendMessageEmbeds(builder.build()).queue();
- } else {
- if(response.hasEmbed()) {
- event.getHook().editOriginalEmbeds(response.getEmbeds()).queue();
- } else {
- event.getHook().editOriginal(response.getMessage()).queue();
- }
- }
- } catch (Exception e) {
- EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
- .setColor(Color.RED)
- .setTitle(":x: **Error**")
- .setDescription(e.getCause().getMessage());
- event.getHook().editOriginalEmbeds(builder.build()).queue();
- }
-
- }
-
-}
diff --git a/src/main/java/net/tylermurphy/ken/command/Response.java b/src/main/java/net/tylermurphy/ken/command/Response.java
index 9b87905..6f6b339 100644
--- a/src/main/java/net/tylermurphy/ken/command/Response.java
+++ b/src/main/java/net/tylermurphy/ken/command/Response.java
@@ -40,6 +40,8 @@ public class Response {
return new Response("success", "", null, embed);
}
+ public static Response delete() { return new Response("delete", "", null, null); }
+
public Response addPrimaryButton(String callback, String id, String label){
buttons.add(Button.primary(callback + "_" + id ,label));
return this;
@@ -64,6 +66,8 @@ public class Response {
return type.equals("error");
}
+ public boolean remove() { return type.equals("delete"); }
+
public boolean hasEmbed() { return embeds != null; }
public boolean hasFile() { return file != null; }
diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java b/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java
index 147d1df..e2e9485 100644
--- a/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java
+++ b/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java
@@ -4,7 +4,7 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
public class Coinflip {
diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Dice.java b/src/main/java/net/tylermurphy/ken/command/fun/Dice.java
index 8a1fb41..27e7fd2 100644
--- a/src/main/java/net/tylermurphy/ken/command/fun/Dice.java
+++ b/src/main/java/net/tylermurphy/ken/command/fun/Dice.java
@@ -4,8 +4,8 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import java.util.List;
diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Eject.java b/src/main/java/net/tylermurphy/ken/command/fun/Eject.java
index 996f228..ff06b4f 100644
--- a/src/main/java/net/tylermurphy/ken/command/fun/Eject.java
+++ b/src/main/java/net/tylermurphy/ken/command/fun/Eject.java
@@ -2,8 +2,8 @@ package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.interactions.commands.OptionType;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.image.GifFactory;
diff --git a/src/main/java/net/tylermurphy/ken/command/main/AddRole.java b/src/main/java/net/tylermurphy/ken/command/main/AddRole.java
new file mode 100644
index 0000000..d5e9f24
--- /dev/null
+++ b/src/main/java/net/tylermurphy/ken/command/main/AddRole.java
@@ -0,0 +1,44 @@
+package net.tylermurphy.ken.command.main;
+
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Role;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.tylermurphy.ken.Ken;
+import net.tylermurphy.ken.command.Response;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
+import net.tylermurphy.ken.event.annotation.Requirement;
+import org.json.JSONArray;
+
+import java.util.List;
+
+public class AddRole {
+
+ @Command(name="addrole", description="Add a role to the /rolls command on a certain page")
+ @Option(name="role", description="Role to add", type=OptionType.ROLE, required=true)
+ @Option(name="page#", description="Page to add it on", type=OptionType.INTEGER, required=true)
+ @Requirement(Permission.MANAGE_SERVER)
+ public Response execute(Guild guild, List<Object> args) {
+ int page = (int)args.get(1);
+ Role role = (Role)args.get(0);
+ String data = Ken.getInstance().getDatabase().getSelfRoleData().getData(guild.getIdLong(), page);
+ if(data == null){
+ return Response.error("Page "+page+" does not exist. Please add it with /addrolespage");
+ }
+ JSONArray array = new JSONArray(data);
+ for(Object o : array){
+ if((long) o == role.getIdLong()) return Response.error("Role is already on that page");
+ }
+ if(array.length() == 15) return Response.error("Each page has a max of 15 roles");
+ array.put(role.getId());
+ data = array.toString();
+ boolean result = Ken.getInstance().getDatabase().getSelfRoleData().setData(guild.getIdLong(), page, data);
+ if(result){
+ return Response.success("Added "+ role +" to page "+page+" successfully");
+ } else {
+ return Response.error("Failed to add role to page");
+ }
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/ken/command/main/AddRolesPage.java b/src/main/java/net/tylermurphy/ken/command/main/AddRolesPage.java
new file mode 100644
index 0000000..2fbab69
--- /dev/null
+++ b/src/main/java/net/tylermurphy/ken/command/main/AddRolesPage.java
@@ -0,0 +1,40 @@
+package net.tylermurphy.ken.command.main;
+
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.tylermurphy.ken.Ken;
+import net.tylermurphy.ken.command.Response;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
+import net.tylermurphy.ken.event.annotation.Requirement;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.util.List;
+
+public class AddRolesPage {
+
+ @Command(name="addrolespage", description="Add a page to the /rolls command")
+ @Option(name="title", description="Page title", type=OptionType.STRING, required=true)
+ @Option(name="description", description="Description of the page", type=OptionType.STRING, required=true)
+ @Requirement(Permission.MANAGE_SERVER)
+ public Response execute(Guild guild, List<Object> args){
+ String data = Ken.getInstance().getDatabase().getSelfRoleData().getData(guild.getIdLong(), 0);
+ JSONArray array;
+ if(data == null) array = new JSONArray();
+ else array = new JSONArray(data);
+ JSONObject page = new JSONObject();
+ page.put("title", args.get(0));
+ page.put("description", args.get(1));
+ array.put(page);
+ data = array.toString();
+ boolean result = Ken.getInstance().getDatabase().getSelfRoleData().setData(guild.getIdLong(), 0, data);
+ if(result){
+ return Response.success("Added new page called "+args.get(0)+" successfully");
+ } else {
+ return Response.error("Failed to create page");
+ }
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/ken/command/main/AddSelfRole.java b/src/main/java/net/tylermurphy/ken/command/main/AddSelfRole.java
deleted file mode 100644
index 3620b41..0000000
--- a/src/main/java/net/tylermurphy/ken/command/main/AddSelfRole.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package net.tylermurphy.ken.command.main;
-
-import net.tylermurphy.ken.command.Response;
-
-import javax.management.relation.Role;
-
-public class AddSelfRole {
-
-// public Response execute(Role role, String){
-//
-// }
-
-}
diff --git a/src/main/java/net/tylermurphy/ken/command/main/DeleteRole.java b/src/main/java/net/tylermurphy/ken/command/main/DeleteRole.java
new file mode 100644
index 0000000..9a271ea
--- /dev/null
+++ b/src/main/java/net/tylermurphy/ken/command/main/DeleteRole.java
@@ -0,0 +1,53 @@
+package net.tylermurphy.ken.command.main;
+
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Role;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.tylermurphy.ken.Ken;
+import net.tylermurphy.ken.command.Response;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
+import net.tylermurphy.ken.event.annotation.Requirement;
+import org.json.JSONArray;
+
+import java.util.List;
+
+public class DeleteRole {
+
+ @Command(name="deleterole", description="Delete a role from the /rolls command on a certain page")
+ @Option(name="role", description="Role to delete", type= OptionType.ROLE, required=true)
+ @Option(name="page#", description="Page to remove it from", type=OptionType.INTEGER, required=true)
+ @Requirement(Permission.MANAGE_SERVER)
+ public Response execute(Guild guild, List<Object> args) {
+ int page = (int)args.get(1);
+ Role role = (Role)args.get(0);
+ String data = Ken.getInstance().getDatabase().getSelfRoleData().getData(guild.getIdLong(), page);
+ if(data == null){
+ return Response.error("Page "+page+" does not exist.");
+ }
+ JSONArray array = new JSONArray(data);
+ int index = getIndex(array, role);
+ if(index == -1){
+ return Response.error("Role is not that page");
+ }
+ array.remove(index);
+ data = array.toString();
+ boolean result = Ken.getInstance().getDatabase().getSelfRoleData().setData(guild.getIdLong(), page, data);
+ if(result){
+ return Response.success("Removed "+ role +" from page "+page+" successfully");
+ } else {
+ return Response.error("Failed to remove role from page");
+ }
+ }
+
+ private int getIndex(JSONArray array, Role role){
+ int i = 0;
+ for(Object o : array){
+ if((long) o == role.getIdLong()) return i;
+ i++;
+ }
+ return -1;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/ken/command/main/DeleteSelfRole.java b/src/main/java/net/tylermurphy/ken/command/main/DeleteRolesPage.java
index de09b9e..22ee85d 100644
--- a/src/main/java/net/tylermurphy/ken/command/main/DeleteSelfRole.java
+++ b/src/main/java/net/tylermurphy/ken/command/main/DeleteRolesPage.java
@@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
-public class DeleteSelfRole {
+public class DeleteRolesPage {
}
diff --git a/src/main/java/net/tylermurphy/ken/command/main/Help.java b/src/main/java/net/tylermurphy/ken/command/main/Help.java
index 281950e..18f432f 100644
--- a/src/main/java/net/tylermurphy/ken/command/main/Help.java
+++ b/src/main/java/net/tylermurphy/ken/command/main/Help.java
@@ -5,8 +5,8 @@ import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.ButtonCallback;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.ButtonCallback;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
public class Help {
diff --git a/src/main/java/net/tylermurphy/ken/command/main/Purge.java b/src/main/java/net/tylermurphy/ken/command/main/Purge.java
index 233c714..f285698 100644
--- a/src/main/java/net/tylermurphy/ken/command/main/Purge.java
+++ b/src/main/java/net/tylermurphy/ken/command/main/Purge.java
@@ -5,9 +5,9 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.interactions.commands.OptionType;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
-import net.tylermurphy.ken.util.Requirement;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
+import net.tylermurphy.ken.event.annotation.Requirement;
import net.tylermurphy.ken.command.Response;
import java.util.List;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/ForceSkip.java b/src/main/java/net/tylermurphy/ken/command/music/ForceSkip.java
index aea0901..bba7e2a 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/ForceSkip.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/ForceSkip.java
@@ -5,7 +5,7 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Join.java b/src/main/java/net/tylermurphy/ken/command/music/Join.java
index 72156c6..64fd20d 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Join.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Join.java
@@ -4,7 +4,7 @@ import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Leave.java b/src/main/java/net/tylermurphy/ken/command/music/Leave.java
index bb85303..5f9b0be 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Leave.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Leave.java
@@ -4,7 +4,7 @@ import net.dv8tion.jda.api.entities.AudioChannel;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Loop.java b/src/main/java/net/tylermurphy/ken/command/music/Loop.java
index 463db3f..d7eb65f 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Loop.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Loop.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/LoopQueue.java b/src/main/java/net/tylermurphy/ken/command/music/LoopQueue.java
index 3d160fc..3cdff39 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/LoopQueue.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/LoopQueue.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/NowPlaying.java b/src/main/java/net/tylermurphy/ken/command/music/NowPlaying.java
index 382a258..ea36dd3 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/NowPlaying.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/NowPlaying.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.PlayerManager;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Pause.java b/src/main/java/net/tylermurphy/ken/command/music/Pause.java
index d8afab7..bdba5bf 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Pause.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Pause.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Play.java b/src/main/java/net/tylermurphy/ken/command/music/Play.java
index e4341f2..c1f25da 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Play.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Play.java
@@ -6,8 +6,8 @@ import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.PlayerManager;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Queue.java b/src/main/java/net/tylermurphy/ken/command/music/Queue.java
index 32d2fc2..98d1a0e 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Queue.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Queue.java
@@ -7,8 +7,8 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.ButtonCallback;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.ButtonCallback;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.PlayerManager;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Remove.java b/src/main/java/net/tylermurphy/ken/command/music/Remove.java
index 5eaffb6..f414420 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Remove.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Remove.java
@@ -7,8 +7,8 @@ import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Resume.java b/src/main/java/net/tylermurphy/ken/command/music/Resume.java
index b7b8f6a..68d8111 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Resume.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Resume.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Skip.java b/src/main/java/net/tylermurphy/ken/command/music/Skip.java
index 1fdbf2a..e16c98b 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Skip.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Skip.java
@@ -8,7 +8,7 @@ import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.PlayerManager;
diff --git a/src/main/java/net/tylermurphy/ken/command/music/Stop.java b/src/main/java/net/tylermurphy/ken/command/music/Stop.java
index 29e196f..c7df165 100644
--- a/src/main/java/net/tylermurphy/ken/command/music/Stop.java
+++ b/src/main/java/net/tylermurphy/ken/command/music/Stop.java
@@ -6,7 +6,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.managers.AudioManager;
import net.tylermurphy.ken.Ken;
-import net.tylermurphy.ken.util.Command;
+import net.tylermurphy.ken.event.annotation.Command;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.music.GuildMusicManager;
import net.tylermurphy.ken.music.MusicPermissions;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Danbooru.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Danbooru.java
index 0e86684..ca18be9 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Danbooru.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Danbooru.java
@@ -7,8 +7,8 @@ import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/E621.java b/src/main/java/net/tylermurphy/ken/command/nsfw/E621.java
index c9ea4fd..580e1d2 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/E621.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/E621.java
@@ -6,8 +6,8 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import org.json.JSONArray;
import org.json.JSONException;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Gelbooru.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Gelbooru.java
index 0e3f06b..167cc2f 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Gelbooru.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Gelbooru.java
@@ -7,8 +7,8 @@ import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.XmlRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import org.json.JSONException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Hentai.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Hentai.java
index 593cd3f..00ec51d 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Hentai.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Hentai.java
@@ -7,8 +7,8 @@ import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Selection;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Selection;
import org.json.JSONException;
import org.json.JSONObject;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Konachan.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Konachan.java
index ad031bd..cb852a8 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Konachan.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Konachan.java
@@ -2,14 +2,13 @@ package net.tylermurphy.ken.command.nsfw;
import net.dv8tion.jda.api.entities.GuildMessageChannel;
import net.dv8tion.jda.api.entities.TextChannel;
-import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.XmlRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import org.json.JSONException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Rule34.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Rule34.java
index acab87d..9c0a264 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Rule34.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Rule34.java
@@ -6,8 +6,8 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.XmlRequest;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import net.tylermurphy.ken.command.Response;
import org.json.JSONException;
import org.w3c.dom.Document;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/Yandere.java b/src/main/java/net/tylermurphy/ken/command/nsfw/Yandere.java
index 61e3af2..3f7b61a 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/Yandere.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/Yandere.java
@@ -7,8 +7,8 @@ import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.XmlRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import org.json.JSONException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
diff --git a/src/main/java/net/tylermurphy/ken/command/nsfw/nHentai.java b/src/main/java/net/tylermurphy/ken/command/nsfw/nHentai.java
index e051b41..3b51eea 100644
--- a/src/main/java/net/tylermurphy/ken/command/nsfw/nHentai.java
+++ b/src/main/java/net/tylermurphy/ken/command/nsfw/nHentai.java
@@ -9,9 +9,9 @@ import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.HTTPMethod;
import net.tylermurphy.ken.api.JsonRequest;
import net.tylermurphy.ken.command.Response;
-import net.tylermurphy.ken.util.ButtonCallback;
-import net.tylermurphy.ken.util.Command;
-import net.tylermurphy.ken.util.Option;
+import net.tylermurphy.ken.event.annotation.ButtonCallback;
+import net.tylermurphy.ken.event.annotation.Command;
+import net.tylermurphy.ken.event.annotation.Option;
import org.json.JSONArray;
import org.json.JSONObject;
diff --git a/src/main/java/net/tylermurphy/ken/database/SelfRoleTable.java b/src/main/java/net/tylermurphy/ken/database/SelfRoleTable.java
index d4c2a92..5411bd7 100644
--- a/src/main/java/net/tylermurphy/ken/database/SelfRoleTable.java
+++ b/src/main/java/net/tylermurphy/ken/database/SelfRoleTable.java
@@ -10,12 +10,13 @@ public class SelfRoleTable {
public SelfRoleTable(Database database){
- String sql = "CREATE TABLE IF NOT EXISTS self_role_data (\n"
- + " guild_id BIGINT NOT NULL,\n"
- + " page INT NOT NULL,\n"
- + " data TEXT NOT NULL,"
- + " PRIMARY KEY (guild_id,page)\n"
- + ");";
+ String sql = """
+ CREATE TABLE IF NOT EXISTS self_role_data (
+ guild_id BIGINT NOT NULL,
+ page INT NOT NULL,
+ data TEXT NOT NULL,
+ PRIMARY KEY (guild_id,page)
+ );""";
try(Connection connection = database.connect(); Statement statement = connection.createStatement()) {
statement.executeUpdate(sql);
@@ -53,4 +54,30 @@ public class SelfRoleTable {
}
}
+ public boolean deleteData(long guildId, int page){
+ String sql = "DELETE FROM self_role_data WHERE guild_id = ? AND page = ?; UPDATE self_role_data SET page = page - 1 WHERE guild_id = ? AND page > ?;";
+ try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setLong(1, guildId);
+ statement.setInt(2, page);
+ statement.setLong(3, guildId);
+ statement.setInt(4, page);
+ return statement.executeUpdate() != 0;
+ } catch (SQLException e) {
+ Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
+ return false;
+ }
+ }
+
+ public int getPages(long guildId) {
+ String sql = "SELECT MAX(page) AS pageCount FROM self_role_data WHERE guild_id = ?";
+ try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setLong(1, guildId);
+ ResultSet rs = statement.executeQuery();
+ return rs.getInt("pageCount");
+ } catch (SQLException e) {
+ Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
+ return -1;
+ }
+ }
+
}
diff --git a/src/main/java/net/tylermurphy/ken/event/Responder.java b/src/main/java/net/tylermurphy/ken/event/Responder.java
new file mode 100644
index 0000000..ba1d587
--- /dev/null
+++ b/src/main/java/net/tylermurphy/ken/event/Responder.java
@@ -0,0 +1,234 @@
+package net.tylermurphy.ken.event;
+
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.GuildMessageChannel;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
+import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.InteractionHook;
+import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
+import net.dv8tion.jda.api.interactions.commands.OptionMapping;
+import net.dv8tion.jda.api.interactions.components.buttons.Button;
+import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
+import net.dv8tion.jda.api.utils.FileUpload;
+import net.tylermurphy.ken.Ken;
+import net.tylermurphy.ken.command.Register;
+import net.tylermurphy.ken.command.Response;
+import net.tylermurphy.ken.command.fun.*;
+import net.tylermurphy.ken.command.main.*;
+import net.tylermurphy.ken.command.music.*;
+import net.tylermurphy.ken.command.music.Queue;
+import net.tylermurphy.ken.command.nsfw.*;
+
+import java.awt.*;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.List;
+
+public class Responder extends ListenerAdapter {
+
+ private final Register register;
+
+ public Responder(JDA api) {
+ this.register = new Register(api);
+ }
+
+ public void registerCommands(){
+ Object[] objects = new Object[]{
+ new Coinflip(),
+ new Dice(),
+ new Eject(),
+ new AddRole(),
+ new DeleteRole(),
+ new Help(),
+ new Purge(),
+ new Roles(),
+ new ForceSkip(),
+ new Join(),
+ new Leave(),
+ new Loop(),
+ new LoopQueue(),
+ new NowPlaying(),
+ new Pause(),
+ new Play(),
+ new Queue(),
+ new Remove(),
+ new Resume(),
+ new Skip(),
+ new Stop(),
+ new Danbooru(),
+ new E621(),
+ new Gelbooru(),
+ new Hentai(),
+ new Konachan(),
+ new nHentai(),
+ new Rule34(),
+ new Yandere(),
+ };
+ Arrays.stream(objects).forEach(register::register);
+ }
+
+ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
+
+ // Make sure the Bot can Talk
+ if(!event.getChannel().canTalk()) return;
+
+ // Bots are not allowed to use commands
+ if (event.getMember() == null || event.getUser().isBot()) return;
+
+ // Get Command Information From Invoke
+ final String invoke = event.getName().toLowerCase(Locale.ROOT);
+
+ Method method = register.getCommand(invoke);
+
+ // Check Permissions
+ if(!event.getMember().hasPermission(register.getPermission(invoke))) {
+ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
+ .appendDescription(":x: **Invalid Permissions**\n")
+ .appendDescription("You require the "+ register.getPermission(invoke)+" permission to use this command.");
+ event.getHook().sendMessageEmbeds(builder.build()).queue();
+ return;
+ }
+
+ // Get slash command options if there are any
+ List<Object> args = getOptions(event.getOptions());
+
+ // Get parameters to send to Method
+ Object[] parameters = new Object[method.getParameterTypes().length];
+ Class<?>[] types = method.getParameterTypes();
+ for(int i = 0; i < types.length; i++){
+ if(types[i] == Member.class){
+ parameters[i] = event.getMember();
+ } else if(types[i] == GuildMessageChannel.class){
+ parameters[i] = event.getGuildChannel();
+ } else if(types[i] == Guild.class) {
+ parameters[i] = event.getGuild();
+ } else if(types[i] == List.class) {
+ parameters[i] = args;
+ } else {
+ parameters[i] = null;
+ }
+ }
+
+ // Invoke Method and Respond to User
+ try {
+ Object temp = method.invoke(register.getHandle(method.getDeclaringClass().getName()), parameters);
+ Response response = (Response)temp;
+ reply(response, event);
+ } catch (Exception e) {
+ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
+ .setColor(Color.RED)
+ .setTitle(":x: **Error**")
+ .setDescription(e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
+ event.replyEmbeds(builder.build()).setEphemeral(true).queue();
+ e.printStackTrace();
+ }
+ }
+
+ public void onButtonInteraction(ButtonInteractionEvent event) {
+
+ // Make sure the Bot can Talk
+ if(!event.getChannel().canTalk()) return;
+ // Bots are not allowed to use commands
+ if (event.getMember() == null || event.getUser().isBot()) return;
+
+ // Get Command Information From Invoke
+ final String invoke = event.getComponentId().toLowerCase(Locale.ROOT).split("_")[0];
+ Method method = register.getButtonCallback(invoke);
+
+ // Defer Reply
+ event.deferEdit().queue();
+
+ // Get parameters to send to Method
+ Object[] parameters = new Object[method.getParameterTypes().length];
+ Class<?>[] types = method.getParameterTypes();
+ for(int i = 0; i < types.length; i++){
+ if(types[i] == Member.class){
+ parameters[i] = event.getMember();
+ } else if(types[i] == GuildMessageChannel.class){
+ parameters[i] = event.getGuildChannel();
+ } else if(types[i] == Guild.class) {
+ parameters[i] = event.getGuild();
+ } else if(types[i] == Button.class) {
+ parameters[i] = event.getButton();
+ } else if(types[i] == Message.class) {
+ parameters[i] = event.getMessage();
+ } else if(types[i] == String.class) {
+ parameters[i] = event.getComponentId().substring(invoke.length()+1);
+ } else {
+ parameters[i] = null;
+ }
+ }
+
+ // Invoke Method and Respond to User
+ try {
+ Object temp = method.invoke(register.getHandle(method.getDeclaringClass().getName()), parameters);
+ Response response = (Response) temp;
+ edit(response, event.getHook());
+ } catch (Exception e) {
+ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
+ .setColor(Color.RED)
+ .setTitle(":x: **Error**")
+ .setDescription(e.getCause().getMessage());
+ event.getHook().editOriginalEmbeds(builder.build()).queue();
+ }
+
+ }
+
+ private void reply(Response response, IReplyCallback event){
+ if(response.error()) {
+ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
+ .setColor(Color.RED)
+ .setDescription(response.getMessage());
+ event.replyEmbeds(builder.build()).setEphemeral(true).queue();
+ } else {
+ ReplyCallbackAction message;
+ if(response.hasEmbed()) {
+ message = event.replyEmbeds(response.getEmbeds());
+ } else {
+ message = event.reply(response.getMessage());
+ }
+ if(response.hasButtons()) message = message.addActionRow(response.getButtons());
+ if(response.hasFile()) message = message.addFiles(FileUpload.fromData(response.getFile()));
+ message.queue();
+ }
+ }
+
+ private void edit(Response response, InteractionHook hook){
+ if(response.error()) {
+ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
+ .setColor(Color.RED)
+ .setDescription(response.getMessage());
+ hook.sendMessageEmbeds(builder.build()).queue();
+ } else {
+ if(response.hasEmbed()) {
+ hook.editOriginalEmbeds(response.getEmbeds()).queue();
+ } else {
+ hook.editOriginal(response.getMessage()).queue();
+ }
+ }
+ }
+
+ private List<Object> getOptions(List<OptionMapping> options){
+ List<Object> args = new ArrayList<>();
+ options.forEach(option -> {
+ switch (option.getType()) {
+ case STRING -> args.add(option.getAsString());
+ case INTEGER -> args.add(option.getAsInt());
+ case BOOLEAN -> args.add(option.getAsBoolean());
+ case USER -> args.add(option.getAsMember());
+ case CHANNEL -> args.add(option.getAsChannel());
+ case ROLE -> args.add(option.getAsRole());
+ case MENTIONABLE -> args.add(option.getAsMentionable());
+ default -> {
+ }
+ }
+ });
+ return args;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/ken/util/ButtonCallback.java b/src/main/java/net/tylermurphy/ken/event/annotation/ButtonCallback.java
index 83682c0..7b791cb 100644
--- a/src/main/java/net/tylermurphy/ken/util/ButtonCallback.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/ButtonCallback.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/net/tylermurphy/ken/util/Command.java b/src/main/java/net/tylermurphy/ken/event/annotation/Command.java
index 8129555..ba6a5b7 100644
--- a/src/main/java/net/tylermurphy/ken/util/Command.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Command.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/net/tylermurphy/ken/util/Option.java b/src/main/java/net/tylermurphy/ken/event/annotation/Option.java
index 19d1fe4..0b91431 100644
--- a/src/main/java/net/tylermurphy/ken/util/Option.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Option.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import net.dv8tion.jda.api.interactions.commands.OptionType;
diff --git a/src/main/java/net/tylermurphy/ken/util/Options.java b/src/main/java/net/tylermurphy/ken/event/annotation/Options.java
index a7e9690..ed5f6e8 100644
--- a/src/main/java/net/tylermurphy/ken/util/Options.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Options.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/net/tylermurphy/ken/util/Requirement.java b/src/main/java/net/tylermurphy/ken/event/annotation/Requirement.java
index 1ffc83c..7cce41e 100644
--- a/src/main/java/net/tylermurphy/ken/util/Requirement.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Requirement.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/net/tylermurphy/ken/util/Selection.java b/src/main/java/net/tylermurphy/ken/event/annotation/Selection.java
index 4711202..e73cc0f 100644
--- a/src/main/java/net/tylermurphy/ken/util/Selection.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Selection.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import net.dv8tion.jda.api.interactions.commands.OptionType;
diff --git a/src/main/java/net/tylermurphy/ken/util/Selections.java b/src/main/java/net/tylermurphy/ken/event/annotation/Selections.java
index d49ea32..5dc8dac 100644
--- a/src/main/java/net/tylermurphy/ken/util/Selections.java
+++ b/src/main/java/net/tylermurphy/ken/event/annotation/Selections.java
@@ -1,4 +1,4 @@
-package net.tylermurphy.ken.util;
+package net.tylermurphy.ken.event.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;