Compare commits

22 Commits

Author SHA1 Message Date
a3c5eb62ac Merge pull request 'add option ranges' (#20) from feat/option-ranges into dev
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 32s
Publish / Gradle-Publish (push) Successful in 43s
Test / Gradle-Test (push) Successful in 47s
Reviewed-on: #20
2025-03-22 18:42:28 +00:00
996f854ff7 feat(command): add wrapper implementations of option ranges
All checks were successful
github-mirror / push-github (push) Successful in 1m40s
Build / Gradle-Build (push) Successful in 33s
Test / Gradle-Test (push) Successful in 47s
2025-03-22 12:33:21 +01:00
d2eec8b07c feat(command): add option ranges to options 2025-03-22 12:31:25 +01:00
caa2ee7089 refactor(command): move both choices vars to different annotation
All checks were successful
github-mirror / push-github (push) Successful in 1m36s
Build / Gradle-Build (push) Successful in 31s
Publish / Gradle-Publish (push) Successful in 36s
Test / Gradle-Test (push) Successful in 47s
2025-03-18 09:33:53 +01:00
2e5979e6e4 Merge pull request 'migrate to slf4j' (#18) from migrate/slf4j into dev
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 1m45s
Publish / Gradle-Publish (push) Successful in 1m32s
Test / Gradle-Test (push) Successful in 1m38s
Reviewed-on: #18
2025-03-17 19:34:26 +00:00
ab1eb74e85 fix(logging) implement getQualifiedCallerName
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 35s
Test / Gradle-Test (push) Successful in 48s
2025-03-17 14:36:43 +01:00
a5737b9eaa feat(logging): add Fallback logging
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 31s
Test / Gradle-Test (push) Successful in 47s
2025-03-17 14:13:21 +01:00
faca21724c fix(logging): fix wrong getClass method. 2025-03-17 14:13:00 +01:00
4c5e28b679 feat(logging): replace log4j dependency with slf4j and replace imports
All checks were successful
github-mirror / push-github (push) Successful in 3s
Build / Gradle-Build (push) Successful in 38s
Test / Gradle-Test (push) Successful in 51s
2025-03-17 10:52:24 +01:00
33f355e6ea Merge pull request 'improve wrapper and general structure' (#16) from improve/structure into dev
All checks were successful
github-mirror / push-github (push) Successful in 5s
Build / Gradle-Build (push) Successful in 36s
Publish / Gradle-Publish (push) Successful in 32s
Test / Gradle-Test (push) Successful in 48s
Reviewed-on: #16
No new features
2025-03-17 08:26:43 +00:00
d32ac62b4a fix(autocomplete): fix autocomplete using component context objects
All checks were successful
github-mirror / push-github (push) Successful in 1m46s
Build / Gradle-Build (push) Successful in 31s
Test / Gradle-Test (push) Successful in 59s
2025-03-17 08:37:11 +01:00
e7c35d9308 refactor(core): remove redundant distinct method and its uses
All checks were successful
github-mirror / push-github (push) Successful in 4s
Build / Gradle-Build (push) Successful in 32s
Test / Gradle-Test (push) Successful in 46s
2025-03-17 00:16:26 +01:00
d4a91f3251 fix(core): fix wrong equality method and refactor a bit 2025-03-17 00:15:10 +01:00
bce4ce7812 fix(wrapper): add condition for CommandRegisterer if api is null 2025-03-16 23:35:39 +01:00
bae077654e refactor(Discord4J): implement CommandRegisterer refactor
Some checks failed
github-mirror / push-github (push) Successful in 1m44s
Build / Gradle-Build (push) Successful in 55s
Test / Gradle-Test (push) Failing after 41s
2025-03-16 17:16:26 +01:00
203498de68 refactor(javacord): implement CommandRegisterer refactor 2025-03-16 17:07:14 +01:00
24df1731da refactor(command): add CommandRegisterer 2025-03-16 17:06:37 +01:00
e3fc10a1ce fix(util): ObjectListAggregator syntax 2025-03-16 02:48:24 +01:00
78cacb7eb6 feat(util): add ObjectListAggregator 2025-03-16 02:47:16 +01:00
7287d44645 refactor(util): add multiple key support to ObjectAggregator 2025-03-16 02:46:55 +01:00
630c8ddee5 feat(register): add convenience getter 2025-03-16 01:49:24 +01:00
4e27e6ce56 feat(struct): introduce ObjectAggregator 2025-03-16 01:36:23 +01:00
37 changed files with 362 additions and 158 deletions

View File

@@ -3,7 +3,7 @@
[versions] [versions]
junit-jupiter = "5.10.2" junit-jupiter = "5.10.2"
log4j = "2.24.1" slf4j = "2.0.17"
javacord = "3.8.0" javacord = "3.8.0"
discord4j = "3.2.7" discord4j = "3.2.7"
geantyref = "2.0.0" geantyref = "2.0.0"
@@ -11,7 +11,7 @@ mockito = "5.15.2"
[libraries] [libraries]
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-api", version.ref = "log4j"} slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j"}
javacord = { module = "org.javacord:javacord", version.ref = "javacord"} javacord = { module = "org.javacord:javacord", version.ref = "javacord"}
discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"} discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"}
geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"} geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"}

View File

@@ -20,7 +20,7 @@ dependencies {
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher") testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.log4j) implementation(libs.slf4j)
implementation(libs.geantyref) implementation(libs.geantyref)
} }

View File

@@ -1,6 +1,6 @@
package net.tomatentum.marinara; package net.tomatentum.marinara;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.registry.InteractionCheckRegistry; import net.tomatentum.marinara.registry.InteractionCheckRegistry;
import net.tomatentum.marinara.registry.InteractionRegistry; import net.tomatentum.marinara.registry.InteractionRegistry;

View File

@@ -5,7 +5,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.util.ReflectionUtil; import net.tomatentum.marinara.util.ReflectionUtil;
@@ -27,7 +27,7 @@ public record AppliedCheck(InteractionCheck<?> check, Annotation annotation) {
logger.debug("Pre Check {} {} with context {}", check.getClass().getName(), result ? "succeeded" : "failed", context.toString()); logger.debug("Pre Check {} {} with context {}", check.getClass().getName(), result ? "succeeded" : "failed", context.toString());
return result; return result;
} catch (IllegalAccessException | InvocationTargetException | SecurityException e) { } catch (IllegalAccessException | InvocationTargetException | SecurityException e) {
logger.fatal(e); logger.error("Failed executing pre-check", e);
return false; return false;
} }
} }
@@ -43,7 +43,7 @@ public record AppliedCheck(InteractionCheck<?> check, Annotation annotation) {
logger.debug("Executing post check {} with context {}", check.getClass().getName(), context.toString()); logger.debug("Executing post check {} with context {}", check.getClass().getName(), context.toString());
method.invoke(check, context, annotation); method.invoke(check, context, annotation);
} catch (IllegalAccessException | InvocationTargetException | SecurityException e) { } catch (IllegalAccessException | InvocationTargetException | SecurityException e) {
logger.fatal(e); logger.error("Failed executing post-check", e);
} }
} }

View File

@@ -4,8 +4,9 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.commands.annotation.CommandChoices;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice;
@@ -18,10 +19,11 @@ import net.tomatentum.marinara.util.LoggerUtil;
public class SlashCommandDefinition { public class SlashCommandDefinition {
public static SlashCommandOptionChoice[] getActualChoices(SlashCommandOption option) { public static SlashCommandOptionChoice[] getActualChoices(SlashCommandOption option) {
SlashCommandOptionChoice[] choices = option.choices(); CommandChoices choices = option.choices();
if (choices.length <= 0 && !option.choiceEnum().equals(PlaceHolderEnum.class)) SlashCommandOptionChoice[] actualChoices = choices.value();
choices = EnumChoices.of(option.choiceEnum()).choices(); if (choices.value().length <= 0 && !choices.cenum().equals(PlaceHolderEnum.class))
return choices; actualChoices = EnumChoices.of(choices.cenum()).choices();
return actualChoices;
} }
private Set<InteractionIdentifier> entries; private Set<InteractionIdentifier> entries;
@@ -66,13 +68,13 @@ public class SlashCommandDefinition {
.map(x -> x.parent()) .map(x -> x.parent())
.toList(); .toList();
return InteractionIdentifier.distinct(subCommandGroups).toArray(SlashCommandIdentifier[]::new); return subCommandGroups.toArray(SlashCommandIdentifier[]::new);
} }
public SlashCommandIdentifier[] getSubCommands() { public SlashCommandIdentifier[] getSubCommands() {
if (isRootCommand) if (isRootCommand)
return null; return null;
return InteractionIdentifier.distinct(entries.stream().filter(x -> x.parent() instanceof RootCommandIdentifier).toList()).toArray(SlashCommandIdentifier[]::new); return entries.stream().filter(x -> x.parent() instanceof RootCommandIdentifier).toArray(SlashCommandIdentifier[]::new);
} }
public SlashCommandIdentifier[] getSubCommands(String groupName) { public SlashCommandIdentifier[] getSubCommands(String groupName) {
@@ -84,7 +86,7 @@ public class SlashCommandDefinition {
.map(x -> x.parent().parent()) .map(x -> x.parent().parent())
.toList(); .toList();
return InteractionIdentifier.distinct(subCommands).toArray(SlashCommandIdentifier[]::new); return subCommands.toArray(SlashCommandIdentifier[]::new);
} }
@Override @Override
@@ -95,6 +97,10 @@ public class SlashCommandDefinition {
return this.rootIdentifier().equals(other.rootIdentifier()); return this.rootIdentifier().equals(other.rootIdentifier());
} }
public long[] serverIds() {
return rootIdentifier().serverIds();
}
public Set<InteractionIdentifier> entries() { public Set<InteractionIdentifier> entries() {
return this.entries; return this.entries;
} }

View File

@@ -0,0 +1,8 @@
package net.tomatentum.marinara.interaction.commands.annotation;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption.PlaceHolderEnum;
public @interface CommandChoices {
public SlashCommandOptionChoice[] value() default {};
public Class<? extends Enum<?>> cenum() default PlaceHolderEnum.class;
}

View File

@@ -0,0 +1,6 @@
package net.tomatentum.marinara.interaction.commands.annotation;
public @interface Range {
public double min() default Double.MIN_VALUE;
public double max() default Double.MAX_VALUE;
}

View File

@@ -15,8 +15,8 @@ public @interface SlashCommandOption {
public SlashCommandOptionType type() default SlashCommandOptionType.STRING; public SlashCommandOptionType type() default SlashCommandOptionType.STRING;
public boolean required() default false; public boolean required() default false;
public boolean autocomplete() default false; public boolean autocomplete() default false;
public SlashCommandOptionChoice[] choices() default {}; public Range range() default @Range;
public Class<? extends Enum<?>> choiceEnum() default PlaceHolderEnum.class; public CommandChoices choices() default @CommandChoices;
public static enum PlaceHolderEnum { public static enum PlaceHolderEnum {

View File

@@ -1,8 +1,5 @@
package net.tomatentum.marinara.interaction.ident; package net.tomatentum.marinara.interaction.ident;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.InteractionType;
@@ -37,20 +34,6 @@ public class InteractionIdentifier {
receiver.description = provider.description(); receiver.description = provider.description();
tryAddDescriptions(receiver.parent(), provider.parent()); tryAddDescriptions(receiver.parent(), provider.parent());
} }
/*
* TODO: Might not be the best solution. Propagating to future
* returns only one Identifier per name and takes the first present description
*/
public static Collection<InteractionIdentifier> distinct(List<InteractionIdentifier> identifiers) {
HashMap<String, InteractionIdentifier> distinctIdentifiers = new HashMap<>();
identifiers.forEach((x) -> {
InteractionIdentifier current = distinctIdentifiers.get(x.name());
if (current == null || (current.description().isBlank() && !x.description().isBlank()))
distinctIdentifiers.put(x.name(), x);
});
return distinctIdentifiers.values();
}
private InteractionIdentifier parent; private InteractionIdentifier parent;
private String name; private String name;

View File

@@ -33,7 +33,7 @@ public class AutoCompleteInteractionMethod extends InteractionMethod {
if (autocompleteOptionValue != null) if (autocompleteOptionValue != null)
return autocompleteOptionValue; return autocompleteOptionValue;
return marinara.getWrapper().getContextObjectProvider().getComponentContextObject(context, type); return marinara.getWrapper().getContextObjectProvider().getInteractionContextObject(context, type);
} }
@Override @Override

View File

@@ -7,7 +7,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.Marinara;
import net.tomatentum.marinara.checks.AppliedCheck; import net.tomatentum.marinara.checks.AppliedCheck;
@@ -69,7 +69,7 @@ public abstract class InteractionMethod {
try { try {
method.invoke(handler, getParameters(context)); method.invoke(handler, getParameters(context));
}catch (IllegalAccessException | InvocationTargetException ex) { }catch (IllegalAccessException | InvocationTargetException ex) {
logger.fatal(ex); logger.error("InteractionMethod failed to run", ex);
} }
this.appliedChecks.forEach(x -> x.post(context)); this.appliedChecks.forEach(x -> x.post(context));

View File

@@ -3,7 +3,7 @@ package net.tomatentum.marinara.parser;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.annotation.Button; import net.tomatentum.marinara.interaction.annotation.Button;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;

View File

@@ -6,7 +6,7 @@ import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.checks.AppliedCheck; import net.tomatentum.marinara.checks.AppliedCheck;
import net.tomatentum.marinara.checks.InteractionCheck; import net.tomatentum.marinara.checks.InteractionCheck;

View File

@@ -3,7 +3,7 @@ package net.tomatentum.marinara.parser;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.InteractionType;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
@@ -59,7 +59,7 @@ public class SlashCommandParser implements AnnotationParser {
.build(isAutoComplete); .build(isAutoComplete);
} }
logger.trace("Parsed using SlashCommandParser for method {} with the result:\n{}", ReflectionUtil.getFullMethodName(method), lastIdentifier.toString()); logger.trace("Parsed using SlashCommandParser for method {} with the result: {}", ReflectionUtil.getFullMethodName(method), lastIdentifier.toString());
consumer.accept((SlashCommandIdentifier) lastIdentifier); consumer.accept((SlashCommandIdentifier) lastIdentifier);
} }

View File

@@ -6,7 +6,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.GenericTypeReflector;
import net.tomatentum.marinara.checks.InteractionCheck; import net.tomatentum.marinara.checks.InteractionCheck;

View File

@@ -3,7 +3,7 @@ package net.tomatentum.marinara.registry;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.InteractionType;
import net.tomatentum.marinara.interaction.ident.InteractionIdentifier; import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;

View File

@@ -1,21 +1,22 @@
package net.tomatentum.marinara.registry; package net.tomatentum.marinara.registry;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.Marinara;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.InteractionType; import net.tomatentum.marinara.interaction.InteractionType;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier; import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.util.ObjectAggregator;
import net.tomatentum.marinara.wrapper.IdentifierProvider; import net.tomatentum.marinara.wrapper.IdentifierProvider;
import net.tomatentum.marinara.interaction.methods.InteractionMethod; import net.tomatentum.marinara.interaction.methods.InteractionMethod;
@@ -39,11 +40,12 @@ public class InteractionRegistry {
for (Method method : interactionHandler.getClass().getMethods()) { for (Method method : interactionHandler.getClass().getMethods()) {
InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, marinara); InteractionMethod iMethod = InteractionMethod.create(method, interactionHandler, marinara);
if (iMethod != null) { if (iMethod != null) {
Optional<InteractionEntry> entry = this.interactions.stream().filter(iMethod::equals).findFirst(); Optional<InteractionEntry> oentry = this.interactions.stream()
if (entry.isEmpty()) { .filter(i -> i.identifier().equals(iMethod.identifier()))
interactions.add(new InteractionEntry(iMethod.identifier()).addMethod(iMethod)); .findFirst();
}else
entry.get().addMethod(iMethod); InteractionEntry entry = oentry.orElse(new InteractionEntry(iMethod.identifier())).addMethod(iMethod);
if (oentry.isEmpty()) this.interactions.add(entry);
logger.debug("Added {} method from {}", iMethod.method().getName(), interactionHandler.getClass().getSimpleName()); logger.debug("Added {} method from {}", iMethod.method().getName(), interactionHandler.getClass().getSimpleName());
} }
} }
@@ -51,27 +53,19 @@ public class InteractionRegistry {
} }
public void registerCommands() { public void registerCommands() {
List<SlashCommandDefinition> defs = new ArrayList<>(); List<InteractionIdentifier> slashIdentifiers = interactions.stream()
List<SlashCommandIdentifier> slashIdentifiers = interactions.stream()
.filter((x) -> x.type().equals(InteractionType.COMMAND)) .filter((x) -> x.type().equals(InteractionType.COMMAND))
.map((x) -> (SlashCommandIdentifier)x.identifier()) .map((x) -> x.identifier())
.toList(); .toList();
slashIdentifiers.forEach((ident) -> { SlashCommandDefinition[] defs = new ObjectAggregator<InteractionIdentifier, RootCommandIdentifier, SlashCommandDefinition>(
Optional<SlashCommandDefinition> appDef = defs.stream() i -> Arrays.asList((RootCommandIdentifier)i.rootNode()),
.filter((x) -> x.rootIdentifier().equals(ident.rootNode())) SlashCommandDefinition::addIdentifier,
.findFirst(); SlashCommandDefinition::new)
.aggregate(slashIdentifiers)
.toArray(SlashCommandDefinition[]::new);
if (appDef.isPresent()) marinara.getWrapper().getRegisterer().register(defs);
appDef.get().addIdentifier(ident);
else
defs.add(
new SlashCommandDefinition((RootCommandIdentifier) ident.rootNode())
.addIdentifier(ident));
});
marinara.getWrapper().registerSlashCommands(defs.toArray(SlashCommandDefinition[]::new));
logger.info("Registered all SlashCommands");
} }
public void handle(Object context) { public void handle(Object context) {

View File

@@ -1,21 +1,14 @@
package net.tomatentum.marinara.util; package net.tomatentum.marinara.util;
import java.util.Properties; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.Level; import org.slf4j.helpers.NOPLoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.apache.logging.log4j.util.ProviderUtil;
public class LoggerUtil { public class LoggerUtil {
public static Logger getLogger(String name) { public static Logger getLogger(String name) {
if (ProviderUtil.hasProviders()) { if (LoggerFactory.getILoggerFactory() instanceof NOPLoggerFactory)
return LogManager.getLogger(name); return new SimpleLogger(name);
}else return LoggerFactory.getLogger(name);
return new SimpleLogger(name, Level.DEBUG, true, false, true, true, "yyyy-MM-dd HH:mm:ss.SSSZ", null,
new PropertiesUtil(new Properties()), System.out);
} }
public static Logger getLogger(Class<?> clazz) { public static Logger getLogger(Class<?> clazz) {

View File

@@ -0,0 +1,46 @@
package net.tomatentum.marinara.util;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class ObjectAggregator<O, K, V> {
private Function<O, Iterable<K>> keySupplier;
private BiConsumer<V, O> valueConsumer;
private Function<K, V> defaultGenerator;
public ObjectAggregator(
Function<O, Iterable<K>> keySupplier,
BiConsumer<V, O> valueConsumer,
Function<K, V> defaultGenerator) {
this.keySupplier = keySupplier;
this.valueConsumer = valueConsumer;
this.defaultGenerator = defaultGenerator;
}
public ObjectAggregator(
Function<O, Iterable<K>> keySupplier,
BiConsumer<V, O> valueConsumer,
Supplier<V> defaultGenerator) {
this.keySupplier = keySupplier;
this.valueConsumer = valueConsumer;
this.defaultGenerator = _ -> defaultGenerator.get();
}
public Collection<V> aggregate(Iterable<O> iterator) {
Map<K, V> map = new HashMap<>();
for (O element : iterator) {
Iterable<K> keys = this.keySupplier.apply(element);
for (K key : keys) {
V value = map.getOrDefault(key, this.defaultGenerator.apply(key));
this.valueConsumer.accept(value, element);
map.putIfAbsent(key, value);
}
}
return map.values();
}
}

View File

@@ -0,0 +1,15 @@
package net.tomatentum.marinara.util;
import java.util.ArrayList;
import java.util.function.Function;
public class ObjectListAggregator<O, K, V> extends ObjectAggregator<O, K, ArrayList<V>> {
public ObjectListAggregator(Function<O, Iterable<K>> keySupplier, Function<O, V> valueConsumer) {
super(keySupplier,
(l, o) -> l.add(valueConsumer.apply(o)),
() -> new ArrayList<>());
}
}

View File

@@ -102,6 +102,6 @@ public final class ReflectionUtil {
} }
public static String getFullMethodName(Method method) { public static String getFullMethodName(Method method) {
return method.getClass().getName() + "." + method.getName(); return method.getDeclaringClass().getName() + "." + method.getName();
} }
} }

View File

@@ -0,0 +1,55 @@
package net.tomatentum.marinara.util;
import org.slf4j.Marker;
import org.slf4j.event.Level;
import org.slf4j.helpers.LegacyAbstractLogger;
import org.slf4j.helpers.MessageFormatter;
public class SimpleLogger extends LegacyAbstractLogger {
private String name;
public SimpleLogger(String name) {
this.name = name;
}
@Override
public boolean isTraceEnabled() {
return true;
}
@Override
public boolean isDebugEnabled() {
return true;
}
@Override
public boolean isInfoEnabled() {
return true;
}
@Override
public boolean isWarnEnabled() {
return true;
}
@Override
public boolean isErrorEnabled() {
return true;
}
@Override
protected String getFullyQualifiedCallerName() {
return this.name;
}
@Override
protected void handleNormalizedLoggingCall(Level level, Marker marker, String messagePattern, Object[] arguments,
Throwable throwable) {
String formatted = MessageFormatter.basicArrayFormat(messagePattern, arguments);
System.out.println("[%s] %s => %s".formatted(level, this.name, formatted));
}
}

View File

@@ -4,12 +4,15 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice;
import net.tomatentum.marinara.interaction.ident.InteractionIdentifier; import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;
import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier; import net.tomatentum.marinara.interaction.ident.RootCommandIdentifier;
import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier; import net.tomatentum.marinara.interaction.ident.SlashCommandIdentifier;
import net.tomatentum.marinara.util.LoggerUtil;
public class CommandConverter<A extends Object, O extends Object, C extends Object> { public class CommandConverter<A extends Object, O extends Object, C extends Object> {
@@ -17,6 +20,8 @@ public class CommandConverter<A extends Object, O extends Object, C extends Obje
return new CommandConverter<>(spec); return new CommandConverter<>(spec);
} }
private Logger logger = LoggerUtil.getLogger(getClass());
private Spec<A, O, C> spec; private Spec<A, O, C> spec;
CommandConverter(Spec<A, O, C> spec) { CommandConverter(Spec<A, O, C> spec) {
@@ -24,6 +29,7 @@ public class CommandConverter<A extends Object, O extends Object, C extends Obje
} }
public A convert(SlashCommandDefinition def) { public A convert(SlashCommandDefinition def) {
logger.debug("Converting command {}", def);
List<O> options = new ArrayList<>(); List<O> options = new ArrayList<>();
if (!def.isRootCommand()) { if (!def.isRootCommand()) {
Arrays.stream(def.getSubCommands()).map(this::convertSubCommand).forEach(options::add); Arrays.stream(def.getSubCommands()).map(this::convertSubCommand).forEach(options::add);
@@ -35,17 +41,20 @@ public class CommandConverter<A extends Object, O extends Object, C extends Obje
} }
private O convertSubCommandGroup(SlashCommandDefinition def, InteractionIdentifier identifier) { private O convertSubCommandGroup(SlashCommandDefinition def, InteractionIdentifier identifier) {
logger.debug("Converting subCommandGroup {} of {}", identifier, def);
SlashCommandIdentifier[] subCommands = def.getSubCommands(identifier.name()); SlashCommandIdentifier[] subCommands = def.getSubCommands(identifier.name());
List<O> convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommand).toList(); List<O> convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommand).toList();
return spec.convertSubCommandGroup(identifier, convertedSubCommands); return spec.convertSubCommandGroup(identifier, convertedSubCommands);
} }
private O convertSubCommand(SlashCommandIdentifier identifier) { private O convertSubCommand(SlashCommandIdentifier identifier) {
logger.debug("Converting subCommand {}", identifier);
List<O> options = Arrays.stream(identifier.options()).map(this::convertOption).toList(); List<O> options = Arrays.stream(identifier.options()).map(this::convertOption).toList();
return spec.convertSubCommand(identifier, options); return spec.convertSubCommand(identifier, options);
} }
private O convertOption(SlashCommandOption option) { private O convertOption(SlashCommandOption option) {
logger.debug("Converting option {}", option);
List<C> choices = Arrays.stream(SlashCommandDefinition.getActualChoices(option)).map(spec::convertChoice).toList(); List<C> choices = Arrays.stream(SlashCommandDefinition.getActualChoices(option)).map(spec::convertChoice).toList();
return spec.convertOption(option, choices); return spec.convertOption(option, choices);
} }

View File

@@ -0,0 +1,51 @@
package net.tomatentum.marinara.wrapper;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.util.ObjectAggregator;
public class CommandRegisterer<A extends Object> {
public static <A extends Object> CommandRegisterer<A> of(Strategy<A> strategy, CommandConverter<A, ?, ?> converter) {
return new CommandRegisterer<A>(strategy, converter);
}
private Logger logger = LoggerUtil.getLogger(getClass());
private Strategy<A> strategy;
private CommandConverter<A, ?, ?> converter;
CommandRegisterer(Strategy<A> strategy, CommandConverter<A, ?, ?> converter) {
this.strategy = strategy;
this.converter = converter;
}
public void register(SlashCommandDefinition[] slashDefs) {
Set<ServerCommandList<A>> serverCommands = new ObjectAggregator<SlashCommandDefinition, Long, ServerCommandList<A>>(
def -> Arrays.stream(def.serverIds()).boxed().toList(),
(l, o) -> l.add(converter.convert(o)),
ServerCommandList::new)
.aggregate(Arrays.asList(slashDefs)).stream()
.collect(Collectors.toSet());
Set<A> globalCommands = Arrays.stream(slashDefs)
.filter(x -> x.serverIds().length <= 0)
.map(converter::convert)
.collect(Collectors.toSet());
serverCommands.forEach(strategy::registerServer);
strategy.registerGlobal(globalCommands);
logger.info("Registered all SlashCommands");
}
public interface Strategy<A extends Object> {
void registerServer(ServerCommandList<A> commands);
void registerGlobal(Set<A> defs);
}
}

View File

@@ -7,7 +7,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.GenericTypeReflector;
import net.tomatentum.marinara.interaction.ident.InteractionIdentifier; import net.tomatentum.marinara.interaction.ident.InteractionIdentifier;

View File

@@ -3,9 +3,6 @@ package net.tomatentum.marinara.wrapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
public abstract class LibraryWrapper { public abstract class LibraryWrapper {
private List<Consumer<Object>> interactionSubscriber; private List<Consumer<Object>> interactionSubscriber;
@@ -25,8 +22,7 @@ public abstract class LibraryWrapper {
interactionSubscriber.remove(consumer); interactionSubscriber.remove(consumer);
} }
public abstract void registerSlashCommands(SlashCommandDefinition[] defs); public abstract CommandRegisterer<?> getRegisterer();
public abstract IdentifierProvider createIdentifierProvider(); public abstract IdentifierProvider createIdentifierProvider();
public abstract ContextObjectProvider getContextObjectProvider(); public abstract ContextObjectProvider getContextObjectProvider();

View File

@@ -0,0 +1,16 @@
package net.tomatentum.marinara.wrapper;
import java.util.HashSet;
public class ServerCommandList<A> extends HashSet<A>{
private long serverId;
public ServerCommandList(long serverId) {
this.serverId = serverId;
}
public long serverId() {
return serverId;
}
}

View File

@@ -19,11 +19,12 @@ dependencies {
// Use JUnit Jupiter for testing. // Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testImplementation(libs.mockito) testImplementation(libs.mockito)
testImplementation(libs.discord4j)
testRuntimeOnly("org.junit.platform:junit-platform-launcher") testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.log4j) implementation(libs.slf4j)
implementation(libs.discord4j) { implementation(libs.discord4j) {
// exclude(module="discord4j-voice") exclude(module="discord4j-voice")
} }
implementation(libs.geantyref) implementation(libs.geantyref)
implementation(project(":lib")) implementation(project(":lib"))

View File

@@ -56,6 +56,10 @@ public class Discord4JConverterSpec implements CommandConverter.Spec<Application
.description(option.description()) .description(option.description())
.required(option.required()) .required(option.required())
.autocomplete(option.autocomplete()) .autocomplete(option.autocomplete())
.minLength(Double.valueOf(option.range().min()).intValue())
.minValue(option.range().min())
.maxLength(Double.valueOf(option.range().max()).intValue())
.maxValue(option.range().max())
.choices(choices) .choices(choices)
.build(); .build();
} }

View File

@@ -0,0 +1,32 @@
package net.tomatentum.marinara.wrapper.discord4j;
import java.util.ArrayList;
import java.util.Set;
import discord4j.core.GatewayDiscordClient;
import discord4j.discordjson.json.ApplicationCommandRequest;
import discord4j.rest.service.ApplicationService;
import net.tomatentum.marinara.wrapper.CommandRegisterer;
import net.tomatentum.marinara.wrapper.ServerCommandList;
public class Discord4JRegistererStrategy implements CommandRegisterer.Strategy<ApplicationCommandRequest> {
private ApplicationService appService;
private long applicationId;
public Discord4JRegistererStrategy(GatewayDiscordClient api) {
this.appService = api.getRestClient().getApplicationService();
this.applicationId = api.getRestClient().getApplicationId().block();
}
@Override
public void registerServer(ServerCommandList<ApplicationCommandRequest> commands) {
appService.bulkOverwriteGuildApplicationCommand(applicationId, commands.serverId(), new ArrayList<>(commands));
}
@Override
public void registerGlobal(Set<ApplicationCommandRequest> defs) {
appService.bulkOverwriteGlobalApplicationCommand(applicationId, new ArrayList<>(defs));
}
}

View File

@@ -1,23 +1,19 @@
package net.tomatentum.marinara.wrapper.discord4j; package net.tomatentum.marinara.wrapper.discord4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import org.apache.logging.log4j.Logger; import org.slf4j.Logger;
import discord4j.core.GatewayDiscordClient; import discord4j.core.GatewayDiscordClient;
import discord4j.core.event.domain.interaction.InteractionCreateEvent; import discord4j.core.event.domain.interaction.InteractionCreateEvent;
import discord4j.core.object.command.ApplicationCommandInteractionOption; import discord4j.core.object.command.ApplicationCommandInteractionOption;
import discord4j.core.object.command.ApplicationCommandOption.Type; import discord4j.core.object.command.ApplicationCommandOption.Type;
import discord4j.discordjson.json.ApplicationCommandOptionChoiceData;
import discord4j.discordjson.json.ApplicationCommandOptionData;
import discord4j.discordjson.json.ApplicationCommandRequest; import discord4j.discordjson.json.ApplicationCommandRequest;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.wrapper.CommandConverter; import net.tomatentum.marinara.wrapper.CommandConverter;
import net.tomatentum.marinara.wrapper.CommandRegisterer;
import net.tomatentum.marinara.wrapper.ContextObjectProvider; import net.tomatentum.marinara.wrapper.ContextObjectProvider;
import net.tomatentum.marinara.wrapper.IdentifierProvider; import net.tomatentum.marinara.wrapper.IdentifierProvider;
import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.LibraryWrapper;
@@ -37,47 +33,28 @@ public class Discord4JWrapper extends LibraryWrapper {
.filter(o -> !o.getType().equals(Type.SUB_COMMAND) && !o.getType().equals(Type.SUB_COMMAND_GROUP)) .filter(o -> !o.getType().equals(Type.SUB_COMMAND) && !o.getType().equals(Type.SUB_COMMAND_GROUP))
.toList(); .toList();
private GatewayDiscordClient api;
private Discord4JContextObjectProvider contextObjectProvider; private Discord4JContextObjectProvider contextObjectProvider;
private CommandConverter<ApplicationCommandRequest, ApplicationCommandOptionData, ApplicationCommandOptionChoiceData> commandConverter; private CommandRegisterer<ApplicationCommandRequest> commandRegisterer;
private Logger logger = LoggerUtil.getLogger(getClass()); private Logger logger = LoggerUtil.getLogger(getClass());
public Discord4JWrapper(GatewayDiscordClient api) { public Discord4JWrapper(GatewayDiscordClient api) {
this.api = api;
this.contextObjectProvider = new Discord4JContextObjectProvider(); this.contextObjectProvider = new Discord4JContextObjectProvider();
this.commandConverter = CommandConverter.of(new Discord4JConverterSpec()); var converter = CommandConverter.of(new Discord4JConverterSpec());
if (api != null) if (api != null) {
this.commandRegisterer = CommandRegisterer.of(new Discord4JRegistererStrategy(api), converter);
api.on(InteractionCreateEvent.class) api.on(InteractionCreateEvent.class)
.subscribe(event -> handleInteraction(event)); .subscribe(event -> handleInteraction(event));
else }else
logger.warn("GatewayDiscordClient was null so no Events were subscribed to."); logger.warn("GatewayDiscordClient was null so no Events were subscribed to.");
logger.info("Discord4J wrapper loaded!"); logger.info("Discord4J wrapper loaded!");
} }
@Override @Override
public void registerSlashCommands(SlashCommandDefinition[] defs) { public CommandRegisterer<?> getRegisterer() {
HashMap<Long, List<ApplicationCommandRequest>> serverCommands = new HashMap<>(); return this.commandRegisterer;
List<ApplicationCommandRequest> globalCommands = new ArrayList<>();
long applicationId = api.getRestClient().getApplicationId().block();
for (SlashCommandDefinition slashCommandDefinition : defs) {
ApplicationCommandRequest request = this.commandConverter.convert(slashCommandDefinition);
if (slashCommandDefinition.rootIdentifier().serverIds().length > 0) {
for (long serverId : slashCommandDefinition.rootIdentifier().serverIds()) {
serverCommands.putIfAbsent(serverId, new ArrayList<>());
serverCommands.get(serverId).add(request);
}
}else
globalCommands.add(request);
}
for (long serverId : serverCommands.keySet()) {
api.getRestClient().getApplicationService().bulkOverwriteGuildApplicationCommand(applicationId, serverId, serverCommands.get(serverId));
}
api.getRestClient().getApplicationService().bulkOverwriteGlobalApplicationCommand(applicationId, globalCommands);
} }
@Override @Override
@@ -93,5 +70,5 @@ public class Discord4JWrapper extends LibraryWrapper {
public ContextObjectProvider getContextObjectProvider() { public ContextObjectProvider getContextObjectProvider() {
return this.contextObjectProvider; return this.contextObjectProvider;
} }
} }

View File

@@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.commands.annotation.CommandChoices;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType;
@@ -20,7 +21,7 @@ public class TestCommand implements InteractionHandler {
name = "foo", name = "foo",
description = "foo bar is very fooby", description = "foo bar is very fooby",
type = SlashCommandOptionType.STRING, type = SlashCommandOptionType.STRING,
choiceEnum = TestChoiceEnum.class choices = @CommandChoices(cenum = TestChoiceEnum.class)
) )
} }
) )

View File

@@ -21,7 +21,7 @@ dependencies {
testImplementation(libs.mockito) testImplementation(libs.mockito)
testRuntimeOnly("org.junit.platform:junit-platform-launcher") testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.log4j) implementation(libs.slf4j)
implementation(libs.javacord) implementation(libs.javacord)
implementation(libs.geantyref) implementation(libs.geantyref)
implementation(project(":lib")) implementation(project(":lib"))

View File

@@ -51,6 +51,10 @@ public class JavacordConverterSpec implements CommandConverter.Spec<SlashCommand
.setDescription(option.description()) .setDescription(option.description())
.setRequired(option.required()) .setRequired(option.required())
.setAutocompletable(option.autocomplete()) .setAutocompletable(option.autocomplete())
.setMinLength(Double.valueOf(option.range().min()).longValue())
.setDecimalMinValue(option.range().min())
.setMaxLength(Double.valueOf(option.range().max()).longValue())
.setDecimalMaxValue(option.range().max())
.setChoices(choices) .setChoices(choices)
.build(); .build();
} }

View File

@@ -0,0 +1,29 @@
package net.tomatentum.marinara.wrapper.javacord;
import java.util.Set;
import org.javacord.api.DiscordApi;
import org.javacord.api.interaction.SlashCommandBuilder;
import net.tomatentum.marinara.wrapper.CommandRegisterer;
import net.tomatentum.marinara.wrapper.ServerCommandList;
public class JavacordRegistererStrategy implements CommandRegisterer.Strategy<SlashCommandBuilder> {
private DiscordApi api;
public JavacordRegistererStrategy(DiscordApi api) {
this.api = api;
}
@Override
public void registerServer(ServerCommandList<SlashCommandBuilder> commands) {
api.bulkOverwriteServerApplicationCommands(commands.serverId(), commands);
}
@Override
public void registerGlobal(Set<SlashCommandBuilder> defs) {
api.bulkOverwriteGlobalApplicationCommands(defs);
}
}

View File

@@ -1,17 +1,11 @@
package net.tomatentum.marinara.wrapper.javacord; package net.tomatentum.marinara.wrapper.javacord;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import org.javacord.api.DiscordApi; import org.javacord.api.DiscordApi;
import org.javacord.api.interaction.SlashCommandBuilder; import org.javacord.api.interaction.SlashCommandBuilder;
import org.javacord.api.interaction.SlashCommandOption; import org.slf4j.Logger;
import org.javacord.api.interaction.SlashCommandOptionChoice;
import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition;
import net.tomatentum.marinara.wrapper.CommandConverter; import net.tomatentum.marinara.wrapper.CommandConverter;
import net.tomatentum.marinara.wrapper.CommandRegisterer;
import net.tomatentum.marinara.wrapper.ContextObjectProvider; import net.tomatentum.marinara.wrapper.ContextObjectProvider;
import net.tomatentum.marinara.wrapper.IdentifierProvider; import net.tomatentum.marinara.wrapper.IdentifierProvider;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;
@@ -22,43 +16,26 @@ import net.tomatentum.marinara.wrapper.javacord.identifierconverter.SlashCommand
public class JavacordWrapper extends LibraryWrapper { public class JavacordWrapper extends LibraryWrapper {
private DiscordApi api;
private JavacordContextObjectProvider contextObjectProvider; private JavacordContextObjectProvider contextObjectProvider;
private CommandConverter<SlashCommandBuilder, SlashCommandOption, SlashCommandOptionChoice> commandConverter; private CommandRegisterer<SlashCommandBuilder> commandRegisterer;
private Logger logger = LoggerUtil.getLogger(getClass()); private Logger logger = LoggerUtil.getLogger(getClass());
public JavacordWrapper(DiscordApi api) { public JavacordWrapper(DiscordApi api) {
this.api = api;
this.contextObjectProvider = new JavacordContextObjectProvider(); this.contextObjectProvider = new JavacordContextObjectProvider();
this.commandConverter = CommandConverter.of(new JavacordConverterSpec()); var converter = CommandConverter.of(new JavacordConverterSpec());
if (api != null) if (api != null) {
this.commandRegisterer = CommandRegisterer.of(new JavacordRegistererStrategy(api), converter);
api.addInteractionCreateListener((e) -> handleInteraction(e.getInteraction())); api.addInteractionCreateListener((e) -> handleInteraction(e.getInteraction()));
else }else
logger.warn("DiscordApi was null so no Events were subscribed to."); logger.warn("DiscordApi was null so no Events were subscribed to.");
logger.info("Javacord wrapper loaded!"); logger.info("Javacord wrapper loaded!");
} }
@Override @Override
public void registerSlashCommands(SlashCommandDefinition[] defs) { public CommandRegisterer<?> getRegisterer() {
HashMap<Long, Set<SlashCommandBuilder>> serverCommands = new HashMap<>(); return this.commandRegisterer;
Set<SlashCommandBuilder> globalCommands = new HashSet<>();
for (SlashCommandDefinition slashCommandDefinition : defs) {
SlashCommandBuilder builder = commandConverter.convert(slashCommandDefinition);
if (slashCommandDefinition.rootIdentifier().serverIds().length > 0) {
for (long serverId : slashCommandDefinition.rootIdentifier().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 @Override

View File

@@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import org.javacord.api.interaction.SlashCommandInteraction; import org.javacord.api.interaction.SlashCommandInteraction;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.commands.annotation.CommandChoices;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType;
@@ -21,7 +22,7 @@ public class TestCommand implements InteractionHandler {
name = "foo", name = "foo",
description = "foo bar is very fooby", description = "foo bar is very fooby",
type = SlashCommandOptionType.STRING, type = SlashCommandOptionType.STRING,
choiceEnum = TestChoiceEnum.class choices = @CommandChoices(cenum = TestChoiceEnum.class)
) )
} }
) )