-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
13 changed files
with
391 additions
and
10 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/main/java/de/webalf/slotbot/model/annotations/SlashCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package de.webalf.slotbot.model.annotations; | ||
|
||
import de.webalf.slotbot.util.permissions.BotPermissionHelper.Authorization; | ||
import org.atteo.classindex.IndexAnnotated; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import static de.webalf.slotbot.util.permissions.BotPermissionHelper.Authorization.ADMINISTRATIVE; | ||
|
||
/** | ||
* @author Alf | ||
* @since 15.07.2021 | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.TYPE) | ||
@IndexAnnotated | ||
public @interface SlashCommand { | ||
String name(); | ||
|
||
String description(); | ||
|
||
Authorization authorization() default ADMINISTRATIVE; | ||
|
||
int optionPosition() default -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/main/java/de/webalf/slotbot/service/bot/SlashCommandsService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package de.webalf.slotbot.service.bot; | ||
|
||
import de.webalf.slotbot.model.annotations.SlashCommand; | ||
import de.webalf.slotbot.util.bot.CommandClassHelper; | ||
import de.webalf.slotbot.util.bot.SlashCommandUtils; | ||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import net.dv8tion.jda.api.entities.Guild; | ||
import net.dv8tion.jda.api.interactions.commands.build.CommandData; | ||
import net.dv8tion.jda.api.interactions.commands.build.OptionData; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import static de.webalf.slotbot.util.bot.CommandClassHelper.getSlashCommand; | ||
import static de.webalf.slotbot.util.bot.SlashCommandUtils.getCommandPrivileges; | ||
import static de.webalf.slotbot.util.permissions.BotPermissionHelper.Authorization.NONE; | ||
|
||
/** | ||
* @author Alf | ||
* @since 15.07.2021 | ||
*/ | ||
@Service | ||
@Slf4j | ||
@RequiredArgsConstructor(onConstructor_ = @Autowired) | ||
public class SlashCommandsService { | ||
private final CommandClassHelper commandClassHelper; | ||
|
||
/** | ||
* Updates slash commands in the given guild | ||
* | ||
* @param guild to update commands for | ||
*/ | ||
public void updateCommands(@NonNull Guild guild) { | ||
final List<CommandData> commands = SlashCommandUtils.commandToClassMap.values().stream() | ||
.map(slashCommandClass -> { //For each slash command | ||
final SlashCommand slashCommand = getSlashCommand(slashCommandClass); | ||
final CommandData commandData = new CommandData(slashCommand.name().toLowerCase(), slashCommand.description()); //Create Command data | ||
if (slashCommand.optionPosition() >= 0) { //Add options if present | ||
commandData.addOptions(getOptions(slashCommandClass, slashCommand.optionPosition())); | ||
} | ||
if (slashCommand.authorization() != NONE) { | ||
commandData.setDefaultEnabled(false); | ||
} | ||
return commandData; | ||
}).collect(Collectors.toUnmodifiableList()); | ||
|
||
guild.updateCommands().addCommands(commands).queue(updatedCommands -> updatedCommands.forEach(command -> { //Update discord commands | ||
final SlashCommand slashCommand = getSlashCommand(SlashCommandUtils.get(command.getName())); | ||
if (slashCommand.authorization() != NONE) { //Set authorized roles if needed | ||
guild.updateCommandPrivilegesById(command.getIdLong(), getCommandPrivileges(guild, slashCommand)).queue(); | ||
} | ||
})); | ||
} | ||
|
||
private List<OptionData> getOptions(Class<?> commandClass, int optionPosition) { | ||
try { | ||
//noinspection unchecked The class must implement an interface and thus we can assume the correct return type here | ||
return (List<OptionData>) commandClass.getMethod("getOptions", int.class).invoke(commandClassHelper.getConstructor(commandClass), optionPosition); | ||
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { | ||
log.error("Failed to getOptions {}", e.getMessage()); | ||
return Collections.emptyList(); | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/main/java/de/webalf/slotbot/service/bot/command/DiscordSlashCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package de.webalf.slotbot.service.bot.command; | ||
|
||
import de.webalf.slotbot.model.annotations.SlashCommand; | ||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; | ||
import net.dv8tion.jda.api.interactions.commands.build.OptionData; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* @author Alf | ||
* @since 18.07.2021 | ||
*/ | ||
public interface DiscordSlashCommand { | ||
void execute(SlashCommandEvent event); | ||
|
||
/** | ||
* List of all slash command options. For each slash command the index in this list is specified in {@link SlashCommand#optionPosition()} | ||
* | ||
* @return list of every option of all slash commands | ||
*/ | ||
@SuppressWarnings("unused") //Used by SlashCommandsService#getOptions(Class, int) | ||
List<OptionData> getOptions(int optionPosition); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/main/java/de/webalf/slotbot/service/bot/listener/GuildReadyListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package de.webalf.slotbot.service.bot.listener; | ||
|
||
import de.webalf.slotbot.service.bot.SlashCommandsService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import net.dv8tion.jda.api.events.guild.GuildReadyEvent; | ||
import net.dv8tion.jda.api.hooks.ListenerAdapter; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
/** | ||
* @author Alf | ||
* @since 15.07.2021 | ||
*/ | ||
@Slf4j | ||
@RequiredArgsConstructor(onConstructor_ = @Autowired) | ||
public class GuildReadyListener extends ListenerAdapter { | ||
private final SlashCommandsService slashCommandsService; | ||
|
||
@Override | ||
public void onGuildReady(@NotNull GuildReadyEvent event) { | ||
slashCommandsService.updateCommands(event.getGuild()); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/main/java/de/webalf/slotbot/service/bot/listener/SlashCommandListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package de.webalf.slotbot.service.bot.listener; | ||
|
||
import de.webalf.slotbot.exception.BusinessRuntimeException; | ||
import de.webalf.slotbot.exception.ForbiddenException; | ||
import de.webalf.slotbot.exception.ResourceNotFoundException; | ||
import de.webalf.slotbot.util.StringUtils; | ||
import de.webalf.slotbot.util.bot.CommandClassHelper; | ||
import de.webalf.slotbot.util.bot.SlashCommandUtils; | ||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; | ||
import net.dv8tion.jda.api.hooks.ListenerAdapter; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
|
||
import static de.webalf.slotbot.util.bot.InteractionUtils.ephemeralDeferReply; | ||
import static de.webalf.slotbot.util.bot.InteractionUtils.reply; | ||
|
||
/** | ||
* @author Alf | ||
* @since 15.07.2021 | ||
*/ | ||
@Slf4j | ||
@RequiredArgsConstructor(onConstructor_ = @Autowired) | ||
public class SlashCommandListener extends ListenerAdapter { | ||
private final CommandClassHelper commandClassHelper; | ||
|
||
@Override | ||
public void onSlashCommand(@NonNull SlashCommandEvent event) { | ||
final String commandName = event.getName(); | ||
log.debug("Received slash command: {} from {}", commandName, event.getUser().getId()); | ||
|
||
final Class<?> commandClass = SlashCommandUtils.get(commandName); | ||
if (commandClass == null) { | ||
log.error("Received not known slash command: {}", commandName); | ||
return; | ||
} | ||
|
||
ephemeralDeferReply(event); | ||
|
||
try { | ||
commandClass.getMethod("execute", SlashCommandEvent.class).invoke(commandClassHelper.getConstructor(commandClass), event); | ||
} catch (InvocationTargetException e) { | ||
Throwable cause = e.getCause(); | ||
if (cause instanceof BusinessRuntimeException || cause instanceof ForbiddenException || cause instanceof ResourceNotFoundException) { | ||
if (StringUtils.isNotEmpty(cause.getMessage())) { | ||
reply(event, cause.getMessage()); | ||
} else { | ||
reply(event, "Das gesuchte Element kann nicht erreicht werden."); | ||
} | ||
} else { | ||
unknownException(event, commandClass, e); | ||
} | ||
} catch (NoSuchMethodException | IllegalAccessException e) { | ||
unknownException(event, commandClass, e); | ||
} | ||
} | ||
|
||
private void unknownException(SlashCommandEvent event, @NonNull Class<?> commandClass, ReflectiveOperationException e) { | ||
log.error("Failed to execute slash command {} with options {}", commandClass.getName(), event.getOptions(), e); | ||
reply(event, "Tja, da ist wohl was schief gelaufen."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.