Compare commits
	
		
			15 Commits
		
	
	
		
			0c3aeed4f4
			...
			11fd16fa77
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 11fd16fa77 | |||
| bbeb58e5e4 | |||
| e39ac2d67e | |||
| 0f337696c1 | |||
| 9f87f47b1f | |||
| 9d81522429 | |||
| 7888819f6e | |||
| 3d5201329b | |||
| 4b835187b5 | |||
| 3778f45cf3 | |||
| 6bd6021b86 | |||
| b0abb423d3 | |||
| 22f9810f7b | |||
| 9768572577 | |||
| 2cdf574df0 | 
| @@ -2,13 +2,13 @@ | |||||||
| # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format | # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format | ||||||
|  |  | ||||||
| [versions] | [versions] | ||||||
| commons-math3 = "3.6.1" |  | ||||||
| guava = "33.0.0-jre" |  | ||||||
| junit-jupiter = "5.10.2" | junit-jupiter = "5.10.2" | ||||||
| log4j = "2.24.1" | log4j = "2.24.1" | ||||||
|  | javacord = "3.8.0" | ||||||
|  | geantyref = "2.0.0" | ||||||
|  |  | ||||||
| [libraries] | [libraries] | ||||||
| commons-math3 = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } |  | ||||||
| guava = { module = "com.google.guava:guava", version.ref = "guava" } |  | ||||||
| junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } | junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } | ||||||
| log4j = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j"} | log4j = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j"} | ||||||
|  | javacord = { module = "org.javacord:javacord", version.ref = "javacord"} | ||||||
|  | geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"} | ||||||
|   | |||||||
| @@ -1,24 +1,13 @@ | |||||||
| package net.tomatentum.marinara; | package net.tomatentum.marinara; | ||||||
|  |  | ||||||
| import java.lang.reflect.Constructor; |  | ||||||
|  |  | ||||||
| import net.tomatentum.marinara.registry.InteractionRegistry; | import net.tomatentum.marinara.registry.InteractionRegistry; | ||||||
| import net.tomatentum.marinara.wrapper.LibraryWrapper; | import net.tomatentum.marinara.wrapper.LibraryWrapper; | ||||||
|  |  | ||||||
| public class Marinara { | public class Marinara { | ||||||
|      |      | ||||||
|     public static <T extends LibraryWrapper> Marinara load(Class<T> clazz) { |     public static <T extends LibraryWrapper> Marinara load(LibraryWrapper wrapper) { | ||||||
|         try { |  | ||||||
|             Constructor<T> ctor = clazz.getConstructor(); |  | ||||||
|             ctor.setAccessible(true); |  | ||||||
|             T wrapper = ctor.newInstance(); |  | ||||||
|         InteractionRegistry registry = new InteractionRegistry(wrapper); |         InteractionRegistry registry = new InteractionRegistry(wrapper); | ||||||
|         return new Marinara(registry); |         return new Marinara(registry); | ||||||
|         }catch (Exception ex) { |  | ||||||
|             System.err.println(ex); |  | ||||||
|             System.exit(100); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private InteractionRegistry registry; |     private InteractionRegistry registry; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | |||||||
| public class SlashCommandDefinition { | public class SlashCommandDefinition { | ||||||
|     private List<ExecutableSlashCommandDefinition> executableDefinitons; |     private List<ExecutableSlashCommandDefinition> executableDefinitons; | ||||||
|     private SlashCommand slashCommand; |     private SlashCommand slashCommand; | ||||||
|     private boolean isRootCommand = false; |     private boolean isRootCommand; | ||||||
|  |  | ||||||
|     public SlashCommandDefinition(SlashCommand applicationCommand) { |     public SlashCommandDefinition(SlashCommand applicationCommand) { | ||||||
|         this.executableDefinitons = new ArrayList<>(); |         this.executableDefinitons = new ArrayList<>(); | ||||||
| @@ -23,16 +23,14 @@ public class SlashCommandDefinition { | |||||||
|         if (def.applicationCommand() != null) { |         if (def.applicationCommand() != null) { | ||||||
|             if (slashCommand == null) |             if (slashCommand == null) | ||||||
|                 this.slashCommand = def.applicationCommand(); |                 this.slashCommand = def.applicationCommand(); | ||||||
|             if (!this.slashCommand.equals(def.applicationCommand())) |             if (!this.slashCommand.name().equals(def.applicationCommand().name())) | ||||||
|                 throw new IllegalArgumentException(def + ": has a non matching Application Command description. Please edit it to equal all other descriptions or remove it to use other definitions descriptions"); |                 throw new IllegalArgumentException(def + ": has a non matching Application Command description. Please edit it to equal all other descriptions or remove it to use other definitions descriptions"); | ||||||
|         } |         } | ||||||
|         if (isRootCommand) { |  | ||||||
|             if (!def.isRootCommand()) |         if (executableDefinitons.isEmpty()) | ||||||
|                 throw new IllegalArgumentException(def + ": cannot have subcommands and rootcommand definitions together"); |             this.isRootCommand = def.isRootCommand(); | ||||||
|             long subCommandAmount = executableDefinitons.stream() |  | ||||||
|                 .filter((x) -> !x.isRootCommand()) |         if ((isRootCommand && !def.isRootCommand()) || (!isRootCommand && def.isRootCommand())) { | ||||||
|                 .count(); |  | ||||||
|             if (subCommandAmount > 0) |  | ||||||
|             throw new IllegalArgumentException(def + ": cannot have subcommands and rootcommand definitions together"); |             throw new IllegalArgumentException(def + ": cannot have subcommands and rootcommand definitions together"); | ||||||
|         } |         } | ||||||
|          |          | ||||||
| @@ -53,7 +51,7 @@ public class SlashCommandDefinition { | |||||||
|                 subCommandGroupMap.put(x.name(), x); |                 subCommandGroupMap.put(x.name(), x); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return (SubCommandGroup[]) subCommandGroupMap.values().toArray(); |         return subCommandGroupMap.values().toArray(new SubCommandGroup[0]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public SubCommand[] getSubCommands(String groupName) { |     public SubCommand[] getSubCommands(String groupName) { | ||||||
| @@ -76,7 +74,7 @@ public class SlashCommandDefinition { | |||||||
|                 subCommandMap.put(x.name(), x); |                 subCommandMap.put(x.name(), x); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return (SubCommand[]) subCommandMap.values().toArray(); |         return subCommandMap.values().toArray(new SubCommand[0]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public SlashCommand getFullSlashCommand() { |     public SlashCommand getFullSlashCommand() { | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package net.tomatentum.marinara.interaction.methods; | package net.tomatentum.marinara.interaction.methods; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.InvocationTargetException; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| import java.security.InvalidParameterException; | import java.security.InvalidParameterException; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| @@ -52,8 +53,8 @@ public abstract class InteractionMethod { | |||||||
|         } |         } | ||||||
|         method.setAccessible(true); |         method.setAccessible(true); | ||||||
|         try { |         try { | ||||||
|             method.invoke(handler, parameters); |             method.invoke(handler, parameters.toArray()); | ||||||
|         }catch (Exception ex) { |         }catch (IllegalAccessException | InvocationTargetException ex) { | ||||||
|             throw new RuntimeException(ex); |             throw new RuntimeException(ex); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -18,13 +18,16 @@ public class InteractionRegistry { | |||||||
|     private LibraryWrapper wrapper; |     private LibraryWrapper wrapper; | ||||||
|  |  | ||||||
|     public InteractionRegistry(LibraryWrapper wrapper) { |     public InteractionRegistry(LibraryWrapper wrapper) { | ||||||
|  |         this.interactionMethods = new ArrayList<>(); | ||||||
|         this.wrapper = wrapper; |         this.wrapper = wrapper; | ||||||
|         wrapper.subscribeInteractions(this::handle); |         wrapper.subscribeInteractions(this::handle); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void addInteractions(InteractionHandler interactionHandler) { |     public void addInteractions(InteractionHandler interactionHandler) { | ||||||
|         for (Method method : interactionHandler.getClass().getMethods()) { |         for (Method method : interactionHandler.getClass().getMethods()) { | ||||||
|             interactionMethods.add(InteractionMethod.create(method, interactionHandler, wrapper)); |             InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, wrapper); | ||||||
|  |             if (iMethod != null) | ||||||
|  |                 this.interactionMethods.add(iMethod); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,8 +30,8 @@ public final class ReflectionUtil { | |||||||
|         if (!isAnnotationPresent(method, SlashCommand.class)) |         if (!isAnnotationPresent(method, SlashCommand.class)) | ||||||
|             throw new RuntimeException(method.getName() + ": Missing ApplicationCommand Annotation on either Class or Method"); |             throw new RuntimeException(method.getName() + ": Missing ApplicationCommand Annotation on either Class or Method"); | ||||||
|  |  | ||||||
|         if (!(method.isAnnotationPresent(SubCommand.class) &&  |         if ((method.isAnnotationPresent(SubCommand.class) &&  | ||||||
|             isAnnotationPresent(method, SlashCommand.class))) { |             !isAnnotationPresent(method, SlashCommand.class))) { | ||||||
|             throw new RuntimeException(method.getName() + ": Missing ApplicationCommand Annotation on either Method or Class"); |             throw new RuntimeException(method.getName() + ": Missing ApplicationCommand Annotation on either Method or Class"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -12,3 +12,4 @@ plugins { | |||||||
|  |  | ||||||
| rootProject.name = "Marinara" | rootProject.name = "Marinara" | ||||||
| include("lib") | include("lib") | ||||||
|  | include("wrapper:javacord") | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								wrapper/javacord/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								wrapper/javacord/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | /* | ||||||
|  |  * This file was generated by the Gradle 'init' task. | ||||||
|  |  * | ||||||
|  |  * This generated file contains a sample Java library project to get you started. | ||||||
|  |  * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.8/userguide/building_java_projects.html in the Gradle documentation. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | plugins { | ||||||
|  |     // Apply the java-library plugin for API and implementation separation. | ||||||
|  |     `java-library` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | repositories { | ||||||
|  |     // Use Maven Central for resolving dependencies. | ||||||
|  |     mavenCentral() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | dependencies { | ||||||
|  |     // Use JUnit Jupiter for testing. | ||||||
|  |     testImplementation(libs.junit.jupiter) | ||||||
|  |  | ||||||
|  |     testRuntimeOnly("org.junit.platform:junit-platform-launcher") | ||||||
|  |     implementation(libs.log4j) | ||||||
|  |     implementation(libs.javacord) | ||||||
|  |     implementation(libs.geantyref) | ||||||
|  |     implementation(project(":lib")) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply a specific Java toolchain to ease working on different environments. | ||||||
|  | java { | ||||||
|  |     toolchain { | ||||||
|  |         languageVersion = JavaLanguageVersion.of(21) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | tasks.named<Test>("test") { | ||||||
|  |     // Use JUnit Platform for unit tests. | ||||||
|  |     useJUnitPlatform() | ||||||
|  | } | ||||||
| @@ -0,0 +1,159 @@ | |||||||
|  | package net.tomatentum.marinare.wrapper.javacord; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | import org.javacord.api.DiscordApi; | ||||||
|  | import org.javacord.api.interaction.ApplicationCommandInteraction; | ||||||
|  | import org.javacord.api.interaction.SlashCommandBuilder; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteraction; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  |  | ||||||
|  | import io.leangen.geantyref.AnnotationFormatException; | ||||||
|  | import io.leangen.geantyref.TypeFactory; | ||||||
|  | import net.tomatentum.marinara.interaction.InteractionType; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; | ||||||
|  | import net.tomatentum.marinara.wrapper.LibraryWrapper; | ||||||
|  |  | ||||||
|  | public class JavacordWrapper extends LibraryWrapper { | ||||||
|  |  | ||||||
|  |     private DiscordApi api; | ||||||
|  |  | ||||||
|  |     public JavacordWrapper(DiscordApi api) { | ||||||
|  |         this.api = api; | ||||||
|  |         api.addInteractionCreateListener((e) -> handleInteraction(e.getInteraction())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void registerSlashCommands(SlashCommandDefinition[] defs) { | ||||||
|  |         HashMap<Long, Set<SlashCommandBuilder>> serverCommands = new HashMap<>(); | ||||||
|  |         Set<SlashCommandBuilder> globalCommands = new HashSet<>(); | ||||||
|  |         for (SlashCommandDefinition slashCommandDefinition : defs) { | ||||||
|  |             SlashCommandBuilder builder = convertSlashCommand(slashCommandDefinition); | ||||||
|  |             if (slashCommandDefinition.getFullSlashCommand().serverIds().length > 0) { | ||||||
|  |                 for (long serverId : slashCommandDefinition.getFullSlashCommand().serverIds()) { | ||||||
|  |                     serverCommands.putIfAbsent(serverId, new HashSet<>()); | ||||||
|  |                     serverCommands.get(serverId).add(builder); | ||||||
|  |                 } | ||||||
|  |             }else | ||||||
|  |                 globalCommands.add(builder); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (long serverId : serverCommands.keySet()) { | ||||||
|  |             api.bulkOverwriteServerApplicationCommands(serverId, serverCommands.get(serverId)); | ||||||
|  |         } | ||||||
|  |         api.bulkOverwriteGlobalApplicationCommands(globalCommands); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionType getInteractionType(Class<?> clazz) { | ||||||
|  |         if (ApplicationCommandInteraction.class.isAssignableFrom(clazz)) | ||||||
|  |             return InteractionType.COMMAND; | ||||||
|  |  | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Object convertCommandOption(Object context, SlashCommandOptionType type, String optionName) { | ||||||
|  |         if (!(context instanceof SlashCommandInteraction)) | ||||||
|  |             return null; | ||||||
|  |         SlashCommandInteraction interaction = (SlashCommandInteraction) context; | ||||||
|  |         if (!interaction.getArguments().isEmpty()) | ||||||
|  |             return getOptionValue(interaction.getOptionByName(optionName).get(), type); | ||||||
|  |  | ||||||
|  |         SlashCommandInteractionOption subCommandOption = interaction.getOptions().getFirst(); | ||||||
|  |  | ||||||
|  |         if (!subCommandOption.getOptions().isEmpty()) | ||||||
|  |             subCommandOption = subCommandOption.getOptions().getFirst(); | ||||||
|  |  | ||||||
|  |         return getOptionValue(subCommandOption.getOptionByName(optionName).get(), type); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { | ||||||
|  |         if (!(context instanceof SlashCommandInteraction)) | ||||||
|  |             return null; | ||||||
|  |  | ||||||
|  |         SlashCommandInteraction interaction = (SlashCommandInteraction) context; | ||||||
|  |         ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder(); | ||||||
|  |         List<SlashCommandInteractionOption> options = interaction.getOptions(); | ||||||
|  |         try { | ||||||
|  |             builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", interaction.getCommandName()))); | ||||||
|  |             if (!options.getFirst().getArguments().isEmpty()) { | ||||||
|  |                 builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName()))); | ||||||
|  |                 builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getOptions().getFirst().getName()))); | ||||||
|  |             }else | ||||||
|  |                 builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getName()))); | ||||||
|  |         } catch (AnnotationFormatException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return builder.build(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private SlashCommandBuilder convertSlashCommand(SlashCommandDefinition def) { | ||||||
|  |         List<org.javacord.api.interaction.SlashCommandOption> options = new ArrayList<>(); | ||||||
|  |         SlashCommand cmd = def.getFullSlashCommand(); | ||||||
|  |         if (!def.isRootCommand()) { | ||||||
|  |             Arrays.stream(def.getSubCommands(null)).map(this::convertSubCommandDef).forEach(options::add); | ||||||
|  |             Arrays.stream(def.getSubCommandGroups()).map((x) -> convertSubCommandGroupDef(def, x)).forEach(options::add); | ||||||
|  |         }else { | ||||||
|  |             Arrays.stream(cmd.options()).map(this::convertOptionDef).forEach(options::add); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return org.javacord.api.interaction.SlashCommand.with(cmd.name(), cmd.description(), options); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) { | ||||||
|  |         SubCommand[] subCommands = def.getSubCommands(subGroup.name()); | ||||||
|  |         org.javacord.api.interaction.SlashCommandOption[] convertedSubCommands = (org.javacord.api.interaction.SlashCommandOption[]) Arrays.stream(subCommands).map(this::convertSubCommandDef).toArray(); | ||||||
|  |         return org.javacord.api.interaction.SlashCommandOption.createWithOptions(org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND_GROUP, subGroup.name(), subGroup.description(), Arrays.asList(convertedSubCommands)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SubCommand sub) { | ||||||
|  |         List<org.javacord.api.interaction.SlashCommandOption> convertedOptions = new ArrayList<>(); | ||||||
|  |         Arrays.stream(sub.options()).map(this::convertOptionDef).forEach(convertedOptions::add); | ||||||
|  |         return org.javacord.api.interaction.SlashCommandOption.createWithOptions(org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND, sub.name(), sub.description(), convertedOptions); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private org.javacord.api.interaction.SlashCommandOption convertOptionDef(SlashCommandOption option) { | ||||||
|  |         org.javacord.api.interaction.SlashCommandOptionType type = Enum.valueOf(org.javacord.api.interaction.SlashCommandOptionType.class, option.type().toString()); | ||||||
|  |         return org.javacord.api.interaction.SlashCommandOption.create(type, option.name(), option.description(), option.required()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private Object getOptionValue(SlashCommandInteractionOption option, SlashCommandOptionType type) { | ||||||
|  |         switch (type) { | ||||||
|  |             case ATTACHMENT: | ||||||
|  |                 return option.getAttachmentValue().get(); | ||||||
|  |             case BOOLEAN: | ||||||
|  |                 return option.getBooleanValue().get(); | ||||||
|  |             case CHANNEL: | ||||||
|  |                 return option.getChannelValue().get(); | ||||||
|  |             case DECIMAL: | ||||||
|  |                 return option.getDecimalValue().get(); | ||||||
|  |             case LONG: | ||||||
|  |                 return option.getLongValue().get(); | ||||||
|  |             case MENTIONABLE: | ||||||
|  |                 return option.getMentionableValue().get(); | ||||||
|  |             case ROLE: | ||||||
|  |                 return option.getRoleValue().get(); | ||||||
|  |             case STRING: | ||||||
|  |                 return option.getStringValue().get(); | ||||||
|  |             case USER: | ||||||
|  |                 return option.getUserValue().get(); | ||||||
|  |             default: | ||||||
|  |                 return null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,53 @@ | |||||||
|  | package net.tomatentum.marinara.test; | ||||||
|  |  | ||||||
|  | import org.javacord.api.DiscordApi; | ||||||
|  | import org.javacord.api.DiscordApiBuilder; | ||||||
|  | import org.junit.jupiter.api.AfterAll; | ||||||
|  | import org.junit.jupiter.api.BeforeAll; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.jupiter.api.TestInstance; | ||||||
|  | import org.junit.jupiter.api.TestInstance.Lifecycle; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.Marinara; | ||||||
|  | import net.tomatentum.marinara.test.mocks.SlashCommandInteractionMock; | ||||||
|  | import net.tomatentum.marinara.wrapper.LibraryWrapper; | ||||||
|  | import net.tomatentum.marinare.wrapper.javacord.JavacordWrapper; | ||||||
|  | @TestInstance(Lifecycle.PER_CLASS) | ||||||
|  | public class SlashCommandTest { | ||||||
|  |  | ||||||
|  |     String DISCORD_TOKEN = System.getenv("DISCORD_TEST_TOKEN"); | ||||||
|  |     DiscordApi api; | ||||||
|  |  | ||||||
|  |     @BeforeAll | ||||||
|  |     void setUp() { | ||||||
|  |         api = new DiscordApiBuilder() | ||||||
|  |         .setToken(DISCORD_TOKEN) | ||||||
|  |         .login().join(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @AfterAll | ||||||
|  |     void tearDown() { | ||||||
|  |         api.disconnect(); | ||||||
|  |         api = null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     void testSlashCommand() { | ||||||
|  |         Marinara marinara = Marinara.load(new JavacordWrapper(api)); | ||||||
|  |         marinara.getRegistry().addInteractions(new TestCommand()); | ||||||
|  |         marinara.getRegistry().registerCommands(); | ||||||
|  |         System.out.println("Success!"); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     void testSlashCommandExecution() { | ||||||
|  |         LibraryWrapper wrapper = new JavacordWrapper(api); | ||||||
|  |         Marinara marinara = Marinara.load(wrapper); | ||||||
|  |         marinara.getRegistry().addInteractions(new TestCommand()); | ||||||
|  |  | ||||||
|  |         wrapper.handleInteraction(new SlashCommandInteractionMock()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |      | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | package net.tomatentum.marinara.test; | ||||||
|  |  | ||||||
|  | import static org.junit.jupiter.api.Assertions.assertEquals; | ||||||
|  |  | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteraction; | ||||||
|  |  | ||||||
|  | import net.tomatentum.marinara.interaction.InteractionHandler; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; | ||||||
|  | import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; | ||||||
|  |  | ||||||
|  | public class TestCommand implements InteractionHandler { | ||||||
|  |     @SlashCommand( | ||||||
|  |         name = "test",  | ||||||
|  |         description = "testingen", | ||||||
|  |         serverIds = { | ||||||
|  |             1037753048602255440L | ||||||
|  |         }, | ||||||
|  |         options = { | ||||||
|  |             @SlashCommandOption( | ||||||
|  |                 name = "foo", | ||||||
|  |                 description = "foo bar is very fooby", | ||||||
|  |                 type = SlashCommandOptionType.STRING | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |         ) | ||||||
|  |     public void exec(SlashCommandInteraction interaction, String test) { | ||||||
|  |         assertEquals(test, "test"); | ||||||
|  |         System.out.println("Success!"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,147 @@ | |||||||
|  | package net.tomatentum.marinara.test.mocks; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.EnumSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
|  |  | ||||||
|  | import org.javacord.api.DiscordApi; | ||||||
|  | import org.javacord.api.entity.channel.TextChannel; | ||||||
|  | import org.javacord.api.entity.message.component.HighLevelComponent; | ||||||
|  | import org.javacord.api.entity.permission.PermissionType; | ||||||
|  | import org.javacord.api.entity.server.Server; | ||||||
|  | import org.javacord.api.entity.user.User; | ||||||
|  | import org.javacord.api.interaction.DiscordLocale; | ||||||
|  | import org.javacord.api.interaction.InteractionType; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteraction; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionFollowupMessageBuilder; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionImmediateResponseBuilder; | ||||||
|  | import org.javacord.api.interaction.callback.InteractionOriginalResponseUpdater; | ||||||
|  |  | ||||||
|  | public class SlashCommandInteractionMock implements SlashCommandInteraction{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getCommandId() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getCommandId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getCommandIdAsString() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getCommandIdAsString'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getCommandName() { | ||||||
|  |         return "test"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Long> getRegisteredCommandServerId() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getRegisteredCommandServerId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getApplicationId() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getApplicationId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionType getType() { | ||||||
|  |         return InteractionType.APPLICATION_COMMAND; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionImmediateResponseBuilder createImmediateResponder() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'createImmediateResponder'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<InteractionOriginalResponseUpdater> respondLater() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondLater'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<InteractionOriginalResponseUpdater> respondLater(boolean ephemeral) { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondLater'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public CompletableFuture<Void> respondWithModal(String customId, String title, | ||||||
|  |             List<HighLevelComponent> components) { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'respondWithModal'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public InteractionFollowupMessageBuilder createFollowupMessageBuilder() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'createFollowupMessageBuilder'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Server> getServer() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getServer'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<TextChannel> getChannel() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getChannel'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public User getUser() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getUser'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getToken() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getToken'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getVersion() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getVersion'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public DiscordLocale getLocale() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getLocale'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<DiscordLocale> getServerLocale() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getServerLocale'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<EnumSet<PermissionType>> getBotPermissions() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getBotPermissions'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public DiscordApi getApi() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getApi'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public long getId() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getId'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getOptions() { | ||||||
|  |         return Arrays.asList(new SlashCommandInteractionOptionMock()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getArguments() { | ||||||
|  |         return Arrays.asList(new SlashCommandInteractionOptionMock()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getFullCommandName() { | ||||||
|  |         return "test"; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -0,0 +1,97 @@ | |||||||
|  | package net.tomatentum.marinara.test.mocks; | ||||||
|  |  | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
|  |  | ||||||
|  | import org.javacord.api.entity.Attachment; | ||||||
|  | import org.javacord.api.entity.Mentionable; | ||||||
|  | import org.javacord.api.entity.channel.ServerChannel; | ||||||
|  | import org.javacord.api.entity.permission.Role; | ||||||
|  | import org.javacord.api.entity.user.User; | ||||||
|  | import org.javacord.api.interaction.SlashCommandInteractionOption; | ||||||
|  |  | ||||||
|  | public class SlashCommandInteractionOptionMock implements SlashCommandInteractionOption{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getArguments() { | ||||||
|  |         return Collections.emptyList(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getName() { | ||||||
|  |         return "foo"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Boolean> isFocused() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'isFocused'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<String> getStringRepresentationValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getStringRepresentationValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<String> getStringValue() { | ||||||
|  |         return Optional.of("test"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Long> getLongValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getLongValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Boolean> getBooleanValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getBooleanValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<User> getUserValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getUserValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<CompletableFuture<User>> requestUserValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'requestUserValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<ServerChannel> getChannelValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getChannelValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Attachment> getAttachmentValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getAttachmentValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Role> getRoleValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getRoleValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Mentionable> getMentionableValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getMentionableValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<Double> getDecimalValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getDecimalValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Optional<CompletableFuture<Mentionable>> requestMentionableValue() { | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'requestMentionableValue'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<SlashCommandInteractionOption> getOptions() { | ||||||
|  |         return Collections.emptyList(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user