mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-07-03 03:44:32 +00:00
[AB-365] introducing slash commands for a selection of commands
adding method for pinning a message moving suggestion to correct deployment
This commit is contained in:
@@ -13,7 +13,6 @@ import dev.sheldan.abstracto.core.command.model.CommandConfirmationModel;
|
||||
import dev.sheldan.abstracto.core.command.model.CommandConfirmationPayload;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandManager;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandService;
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
@@ -37,7 +36,6 @@ import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.UnexpectedRollbackException;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -63,34 +61,13 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private CommandReceivedHandler self;
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired
|
||||
private EmoteManagementService emoteManagementService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private List<CommandParameterHandler> parameterHandlers;
|
||||
|
||||
@@ -393,7 +370,11 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
|
||||
public CompletableFuture<Parameters> getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message) {
|
||||
List<ParseResult> parsedParameters = new ArrayList<>();
|
||||
List<Parameter> parameters = command.getConfiguration().getParameters();
|
||||
List<Parameter> parameters = command
|
||||
.getConfiguration()
|
||||
.getParameters()
|
||||
.stream()
|
||||
.filter(parameter -> !parameter.getSlashCommandOnly()).collect(Collectors.toList());
|
||||
if (parameters == null || parameters.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(Parameters.builder().parameters(new ArrayList<>()).build());
|
||||
}
|
||||
@@ -507,13 +488,16 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
|
||||
private List<Object> extractParametersFromParsed(List<ParseResult> results) {
|
||||
List<Object> usableParameters = new ArrayList<>();
|
||||
results.forEach(parseResult -> {
|
||||
boolean lastWasRemainder = false;
|
||||
for (ParseResult parseResult : results) {
|
||||
if (parseResult.getParameter().isRemainder() && !parseResult.getParameter().isListParam() && parseResult.getResult() instanceof String) {
|
||||
if (usableParameters.isEmpty() || !(usableParameters.get(usableParameters.size() - 1) instanceof String)) {
|
||||
usableParameters.add(parseResult.getResult());
|
||||
} else {
|
||||
} else if(lastWasRemainder){
|
||||
int lastIndex = usableParameters.size() - 1;
|
||||
usableParameters.set(lastIndex, usableParameters.get(lastIndex).toString() + " " + parseResult.getResult().toString());
|
||||
} else {
|
||||
usableParameters.add(parseResult.getResult());
|
||||
}
|
||||
} else if (parseResult.getParameter().isListParam()) {
|
||||
if (usableParameters.isEmpty()) {
|
||||
@@ -527,7 +511,8 @@ public class CommandReceivedHandler extends ListenerAdapter {
|
||||
} else {
|
||||
usableParameters.add(parseResult.getResult());
|
||||
}
|
||||
});
|
||||
lastWasRemainder = parseResult.getParameter().isRemainder();
|
||||
}
|
||||
return usableParameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
package dev.sheldan.abstracto.core.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandService;
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SlashCommandListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
@Getter
|
||||
private List<Command> commands = new ArrayList<>();
|
||||
|
||||
@Autowired
|
||||
@Qualifier("slashCommandExecutor")
|
||||
private TaskExecutor slashCommandExecutor;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private List<PostCommandExecution> executions;
|
||||
|
||||
public List<Command> getSlashCommands() {
|
||||
if(commands == null || commands.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return commands.stream()
|
||||
.filter(command -> command.getConfiguration()
|
||||
.getSlashCommandConfig().isEnabled())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
|
||||
if(commands == null || commands.isEmpty()) return;
|
||||
CompletableFuture.runAsync(() -> self.executeListenerLogic(event), slashCommandExecutor).exceptionally(throwable -> {
|
||||
log.error("Failed to execute listener logic in async button event.", throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executeListenerLogic(SlashCommandInteractionEvent event) {
|
||||
Optional<Command> potentialCommand = findCommand(event);
|
||||
potentialCommand.ifPresent(command -> {
|
||||
try {
|
||||
commandService.isCommandExecutable(command, event).thenAccept(conditionResult -> {
|
||||
CompletableFuture<CommandResult> commandOutput;
|
||||
if(conditionResult.isResult()) {
|
||||
commandOutput = command.executeSlash(event).thenApply(commandResult -> {
|
||||
log.info("Command {} in server {} was executed.", command.getConfiguration().getName(), event.getGuild().getIdLong());
|
||||
return commandResult;
|
||||
});
|
||||
} else {
|
||||
commandOutput = CompletableFuture.completedFuture(CommandResult.fromCondition(conditionResult));
|
||||
}
|
||||
commandOutput.thenAccept(commandResult -> {
|
||||
self.executePostCommandListener(command, event, commandResult);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Error while handling post execution of command {}", command.getConfiguration().getName(), throwable);
|
||||
CommandResult commandResult = CommandResult.fromError(throwable.getMessage(), throwable);
|
||||
self.executePostCommandListener(command, event, commandResult);
|
||||
return null;
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Error while executing command {}", command.getConfiguration().getName(), throwable);
|
||||
CommandResult commandResult = CommandResult.fromError(throwable.getMessage(), throwable);
|
||||
self.executePostCommandListener(command, event, commandResult);
|
||||
return null;
|
||||
});
|
||||
} catch (Exception exception) {
|
||||
log.error("Error while checking if command {} is executable.", command.getConfiguration().getName(), exception);
|
||||
CommandResult commandResult = CommandResult.fromError(exception.getMessage(), exception);
|
||||
self.executePostCommandListener(command, event, commandResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executePostCommandListener(Command foundCommand, SlashCommandInteractionEvent event, CommandResult result) {
|
||||
for (PostCommandExecution postCommandExecution : executions) {
|
||||
postCommandExecution.executeSlash(event, result, foundCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Command> findCommand(SlashCommandInteractionEvent event) {
|
||||
return commands
|
||||
.stream()
|
||||
.filter(command -> command.getConfiguration().getSlashCommandConfig().isEnabled())
|
||||
.filter(command -> command.getConfiguration().getSlashCommandConfig().matchesInteraction(event.getInteraction()))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void filterPostProcessors() {
|
||||
executions = executions
|
||||
.stream()
|
||||
.filter(PostCommandExecution::supportsSlash)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import dev.sheldan.abstracto.core.command.execution.UnparsedCommandParameterPiec
|
||||
import dev.sheldan.abstracto.core.command.handler.provided.ChannelGroupTypeParameterHandler;
|
||||
import dev.sheldan.abstracto.core.models.database.ChannelGroupType;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupTypeManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -19,9 +18,6 @@ public class ChannelGroupTypeParameterHandlerImpl implements ChannelGroupTypePar
|
||||
@Autowired
|
||||
private ChannelGroupTypeManagementService channelGroupTypeManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public boolean handles(Class clazz, UnparsedCommandParameterPiece value) {
|
||||
return clazz.equals(ChannelGroupType.class) && value.getType().equals(ParameterPieceType.STRING);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.core.command.handler;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.CommandConstants;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.ParameterPieceType;
|
||||
import dev.sheldan.abstracto.core.command.execution.UnparsedCommandParameterPiece;
|
||||
import dev.sheldan.abstracto.core.command.handler.provided.InstantParameterHandler;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Component
|
||||
public class InstantParameterHandlerImpl implements InstantParameterHandler {
|
||||
|
||||
@Override
|
||||
public Object handle(UnparsedCommandParameterPiece input, CommandParameterIterators iterators, Parameter param, Message context, Command command) {
|
||||
return Instant.ofEpochSecond(Long.parseLong((String) input.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(Class clazz, UnparsedCommandParameterPiece value) {
|
||||
return clazz.equals(Instant.class) && value.getType().equals(ParameterPieceType.STRING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return CommandConstants.CORE_HANDLER_PRIORITY;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.command.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.MessageContextCommandListener;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.FeatureActivationListener;
|
||||
import dev.sheldan.abstracto.core.listener.sync.jda.MessageContextCommandListenerBean;
|
||||
@@ -13,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -36,6 +38,9 @@ public class MessageContextCommandFeatureActivationListener implements FeatureAc
|
||||
if(listeners == null || listeners.isEmpty()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
listeners = listeners
|
||||
.stream().filter(command -> command.getFeature().getKey().equals(model.getFeatureName()))
|
||||
.collect(Collectors.toList());
|
||||
Guild guild = guildService.getGuildById(model.getServerId());
|
||||
listeners.forEach(messageContextCommandListener -> {
|
||||
if(featureModeService.necessaryFeatureModesMet(messageContextCommandListener, model.getServerId())) {
|
||||
@@ -1,10 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.command.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.MessageContextCommandListener;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.FeatureActivationListener;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.FeatureDeactivationListener;
|
||||
import dev.sheldan.abstracto.core.listener.sync.jda.MessageContextCommandListenerBean;
|
||||
import dev.sheldan.abstracto.core.models.listener.FeatureActivationListenerModel;
|
||||
import dev.sheldan.abstracto.core.models.listener.FeatureDeactivationListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.ContextCommandService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
@@ -15,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -38,6 +38,9 @@ public class MessageContextCommandFeatureDeactivationListener implements Feature
|
||||
if(listeners == null || listeners.isEmpty()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
listeners = listeners
|
||||
.stream().filter(command -> command.getFeature().getKey().equals(model.getFeatureName()))
|
||||
.collect(Collectors.toList());
|
||||
Guild guild = guildService.getGuildById(model.getServerId());
|
||||
listeners.forEach(messageContextCommandListener -> {
|
||||
if(featureModeService.necessaryFeatureModesMet(messageContextCommandListener, model.getServerId())) {
|
||||
@@ -0,0 +1,65 @@
|
||||
package dev.sheldan.abstracto.core.command.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.SlashCommandListenerBean;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.slash.SlashCommandService;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.FeatureActivationListener;
|
||||
import dev.sheldan.abstracto.core.models.listener.FeatureActivationListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SlashCommandFeatureActivationListener implements FeatureActivationListener {
|
||||
|
||||
@Autowired
|
||||
private SlashCommandListenerBean slashCommandListenerBean;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandService slashCommandService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(FeatureActivationListenerModel model) {
|
||||
List<Command> incomingSlashCommands = slashCommandListenerBean.getSlashCommands()
|
||||
.stream()
|
||||
.filter(command -> command.getFeature().getKey().equals(model.getFeatureName()))
|
||||
.collect(Collectors.toList());
|
||||
if(incomingSlashCommands.isEmpty()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
JDA jda = botService.getInstance();
|
||||
Guild guild = jda.getGuildById(model.getServerId());
|
||||
log.info("Updating slash commands for guild {}.", guild.getIdLong());
|
||||
List<Pair<List<CommandConfiguration>, SlashCommandData>> commandsToUpDate = new ArrayList<>();
|
||||
incomingSlashCommands.forEach(command -> {
|
||||
if(!featureModeService.necessaryFeatureModesMet(command, guild.getIdLong())) {
|
||||
return;
|
||||
}
|
||||
log.info("Updating slash command {} in guild {}.", command.getConfiguration().getName(), guild.getId());
|
||||
slashCommandService.convertCommandConfigToCommandData(command.getConfiguration(), commandsToUpDate);
|
||||
});
|
||||
slashCommandService.addGuildSlashCommands(guild, commandsToUpDate)
|
||||
.thenAccept(commands1 -> log.info("Updating {} slash commands in guild {}.", commandsToUpDate.size(), guild.getIdLong()));
|
||||
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package dev.sheldan.abstracto.core.command.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.SlashCommandListenerBean;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.command.slash.SlashCommandService;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.FeatureDeactivationListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.listener.FeatureDeactivationListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.ISnowflake;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SlashCommandFeatureDeactivationListener implements FeatureDeactivationListener {
|
||||
|
||||
@Autowired
|
||||
private SlashCommandListenerBean slashCommandListenerBean;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandService slashCommandService;
|
||||
|
||||
@Autowired
|
||||
private CommandInServerManagementService commandInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandManagementService commandManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(FeatureDeactivationListenerModel model) {
|
||||
List<Command> commandsToDelete = slashCommandListenerBean.getSlashCommands()
|
||||
.stream()
|
||||
.filter(command -> command.getFeature().getKey().equals(model.getFeatureName()))
|
||||
.collect(Collectors.toList());
|
||||
if(commandsToDelete.isEmpty()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
JDA jda = botService.getInstance();
|
||||
Guild guild = jda.getGuildById(model.getServerId());
|
||||
log.info("Updating slash commands for guild {}.", guild.getIdLong());
|
||||
guild.retrieveCommands().queue(commands -> {
|
||||
List<Long> existingCommands = commands
|
||||
.stream()
|
||||
.filter(command -> command.getType().equals(net.dv8tion.jda.api.interactions.commands.Command.Type.SLASH))
|
||||
.map(ISnowflake::getIdLong)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
log.info("Loaded {} slash commands for guild {}.", commands.size(), guild.getIdLong());
|
||||
Set<Long> commandIdsToDelete = new HashSet<>();
|
||||
List<Long> commandInServerIdsToUnset = new ArrayList<>();
|
||||
AServer server = serverManagementService.loadServer(guild.getIdLong());
|
||||
commandsToDelete.forEach(aCommandToDelete -> {
|
||||
ACommand aCommand = commandManagementService.findCommandByName(aCommandToDelete.getConfiguration().getName());
|
||||
ACommandInAServer commandInServer = commandInServerManagementService.getCommandForServer(aCommand, server);
|
||||
if(commandInServer.getSlashCommandId() != null && existingCommands.contains(commandInServer.getSlashCommandId())) {
|
||||
commandIdsToDelete.add(commandInServer.getSlashCommandId());
|
||||
commandInServerIdsToUnset.add(commandInServer.getSlashCommandId());
|
||||
}
|
||||
});
|
||||
slashCommandService.deleteGuildSlashCommands(guild, new ArrayList<>(commandIdsToDelete), commandInServerIdsToUnset).whenComplete((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.error("Failed to delete {} commands from guild {} for feature {}.", commandIdsToDelete.size(), guild.getIdLong(), model.getFeatureName(), throwable);
|
||||
} else {
|
||||
log.info("Deleted {} commands for guild {} for feature {}.", commandIdsToDelete.size(), guild.getIdLong(), model.getFeatureName());
|
||||
}
|
||||
});
|
||||
},
|
||||
throwable -> log.error("Failed to load commands for guild {}.", guild.getIdLong(), throwable));
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -168,6 +169,16 @@ public class CommandServiceBean implements CommandService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ConditionResult> isCommandExecutable(Command command, SlashCommandInteractionEvent slashCommandInteractionEvent) {
|
||||
if(command instanceof ConditionalCommand) {
|
||||
ConditionalCommand castedCommand = (ConditionalCommand) command;
|
||||
return checkConditions(slashCommandInteractionEvent, command, castedCommand.getConditions());
|
||||
} else {
|
||||
return ConditionResult.fromAsyncSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnParsedCommandParameter getUnParsedCommandParameter(String messageContent, Message message) {
|
||||
return new UnParsedCommandParameter(messageContent, message);
|
||||
@@ -196,6 +207,41 @@ public class CommandServiceBean implements CommandService {
|
||||
.build();
|
||||
}
|
||||
|
||||
private CompletableFuture<ConditionResult> checkConditions(SlashCommandInteractionEvent slashCommandInteractionEvent, Command command, List<CommandCondition> conditions) {
|
||||
if(conditions != null && !conditions.isEmpty()) {
|
||||
List<CompletableFuture<ConditionResult>> futures = new ArrayList<>();
|
||||
for (CommandCondition condition : conditions) {
|
||||
if(condition.isAsync()) {
|
||||
futures.add(condition.shouldExecuteAsync(slashCommandInteractionEvent, command));
|
||||
} else {
|
||||
futures.add(CompletableFuture.completedFuture(condition.shouldExecute(slashCommandInteractionEvent, command)));
|
||||
}
|
||||
}
|
||||
CompletableFuture<ConditionResult> resultFuture = new CompletableFuture<>();
|
||||
CompletableFutureList<ConditionResult> futureList = new CompletableFutureList<>(futures);
|
||||
futureList.getMainFuture().whenComplete((unused, throwable) -> {
|
||||
List<ConditionResult> results = futureList.getObjects();
|
||||
boolean foundResult = false;
|
||||
for (ConditionResult conditionResult : results) {
|
||||
if (!conditionResult.isResult()) {
|
||||
foundResult = true;
|
||||
resultFuture.complete(conditionResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!foundResult) {
|
||||
resultFuture.complete(ConditionResult.fromSuccess());
|
||||
}
|
||||
}).exceptionally(throwable -> {
|
||||
resultFuture.completeExceptionally(throwable);
|
||||
return null;
|
||||
});
|
||||
return resultFuture;
|
||||
} else {
|
||||
return ConditionResult.fromAsyncSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<ConditionResult> checkConditions(CommandContext commandContext, Command command, List<CommandCondition> conditions) {
|
||||
if(conditions != null && !conditions.isEmpty()) {
|
||||
List<CompletableFuture<ConditionResult>> futures = new ArrayList<>();
|
||||
|
||||
@@ -7,9 +7,12 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ResultState;
|
||||
import dev.sheldan.abstracto.core.command.model.condition.GenericConditionModel;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.GuildChannelMember;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.ReactionService;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -23,9 +26,16 @@ public class ConditionPostExecution implements PostCommandExecution {
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext commandContext, CommandResult commandResult, Command command) {
|
||||
if(commandResult.getResult().equals(ResultState.CONDITION) && commandResult.getConditionResult() != null && !commandResult.getConditionResult().isResult() && commandResult.getConditionResult().getConditionDetail() != null) {
|
||||
if(commandResult.getResult().equals(ResultState.CONDITION)
|
||||
&& commandResult.getConditionResult() != null &&
|
||||
!commandResult.getConditionResult().isResult()
|
||||
&& commandResult.getConditionResult().getConditionDetail() != null
|
||||
&& commandResult.getConditionResult().isReportResult()) {
|
||||
reactionService.addReactionToMessage(CoreFeatureConfig.WARN_REACTION_KEY, commandContext.getGuild().getIdLong(), commandContext.getMessage());
|
||||
GenericConditionModel conditionModel = GenericConditionModel
|
||||
.builder()
|
||||
@@ -40,4 +50,30 @@ public class ConditionPostExecution implements PostCommandExecution {
|
||||
channelService.sendEmbedTemplateInTextChannelList(GENERIC_COMMAND_EXCEPTION_MODEL_KEY, conditionModel, commandContext.getChannel());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeSlash(SlashCommandInteractionEvent interaction, CommandResult commandResult, Command command) {
|
||||
if(commandResult.getResult().equals(ResultState.CONDITION)
|
||||
&& commandResult.getConditionResult() != null &&
|
||||
!commandResult.getConditionResult().isResult()
|
||||
&& commandResult.getConditionResult().getConditionDetail() != null
|
||||
&& commandResult.getConditionResult().isReportResult()) {
|
||||
GenericConditionModel conditionModel = GenericConditionModel
|
||||
.builder()
|
||||
.conditionDetail(commandResult.getConditionResult().getConditionDetail())
|
||||
.guildChannelMember(GuildChannelMember
|
||||
.builder()
|
||||
.guild(interaction.getGuild())
|
||||
.textChannel((GuildChannel) interaction.getChannel())
|
||||
.member(interaction.getMember())
|
||||
.build())
|
||||
.build();
|
||||
interactionService.replyEmbed(GENERIC_COMMAND_EXCEPTION_MODEL_KEY, conditionModel, interaction.getInteraction());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSlash() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ResultState;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownService;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -24,4 +25,17 @@ public class CoolDownPostExecution implements PostCommandExecution {
|
||||
commandCoolDownService.updateCoolDowns(command, commandContext);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSlash() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeSlash(SlashCommandInteractionEvent interaction, CommandResult commandResult, Command command) {
|
||||
ResultState result = commandResult.getResult();
|
||||
if(result.equals(ResultState.SUCCESSFUL) || result.equals(ResultState.IGNORED)) {
|
||||
commandCoolDownService.updateCoolDowns(command, interaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -41,4 +42,27 @@ public class ExceptionPostExecution implements PostCommandExecution {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeSlash(SlashCommandInteractionEvent interaction, CommandResult commandResult, Command command) {
|
||||
ResultState result = commandResult.getResult();
|
||||
if(result.equals(ResultState.ERROR)) {
|
||||
Throwable throwable = commandResult.getThrowable();
|
||||
if(throwable != null) {
|
||||
if(throwable instanceof CommandNotFoundException){
|
||||
String configValue = configService.getStringValueOrConfigDefault(CoreFeatureConfig.NO_COMMAND_REPORTING_CONFIG_KEY, interaction.getGuild().getIdLong());
|
||||
if(!BooleanUtils.toBoolean(configValue)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
log.info("Exception handling for exception {}.", throwable.getClass().getSimpleName());
|
||||
exceptionService.reportSlashException(throwable, interaction, command);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean supportsSlash() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -75,6 +76,12 @@ public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
@Override
|
||||
public CoolDownCheckResult allowedToExecuteCommand(Command command, CommandContext context) {
|
||||
Long serverId = context.getGuild().getIdLong();
|
||||
Long channelId = context.getChannel().getIdLong();
|
||||
Long memberId = context.getAuthor().getIdLong();
|
||||
return allowedToExecuteCommand(command, serverId, channelId, memberId);
|
||||
}
|
||||
|
||||
private CoolDownCheckResult allowedToExecuteCommand(Command command, Long serverId, Long channelId, Long memberId) {
|
||||
Instant now = Instant.now();
|
||||
String commandName = command.getConfiguration().getName();
|
||||
Duration serverCooldown = null;
|
||||
@@ -90,7 +97,7 @@ public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
if(storage.getChannelGroupCoolDowns().containsKey(serverId)) {
|
||||
Map<Long, CommandReUseMap> serverMap = storage.getChannelGroupCoolDowns().get(serverId);
|
||||
if(!serverMap.keySet().isEmpty()) {
|
||||
Long channelId = context.getChannel().getIdLong();
|
||||
|
||||
AChannel channel = channelManagementService.loadChannel(channelId);
|
||||
List<AChannelGroup> channelGroups =
|
||||
channelGroupService.getChannelGroupsOfChannelWithType(channel, COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
@@ -108,7 +115,6 @@ public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
if(storage.getMemberCoolDowns().containsKey(serverId)) {
|
||||
Map<Long, CommandReUseMap> serverMap = storage.getMemberCoolDowns().get(serverId);
|
||||
if(!serverMap.keySet().isEmpty()) {
|
||||
Long memberId = context.getAuthor().getIdLong();
|
||||
if(serverMap.containsKey(memberId)) {
|
||||
CommandReUseMap commandReUseMap = serverMap.get(memberId);
|
||||
Duration durationToExecuteIn = getDurationToExecuteIn(now, commandName, commandReUseMap);
|
||||
@@ -121,6 +127,14 @@ public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
return createCooldownCheckResult(serverId, commandName, serverCooldown, channelCooldown, memberCooldown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoolDownCheckResult allowedToExecuteCommand(Command command, SlashCommandInteractionEvent slashCommandInteractionEvent) {
|
||||
Long serverId = slashCommandInteractionEvent.getGuild().getIdLong();
|
||||
Long channelId = slashCommandInteractionEvent.getChannel().getIdLong();
|
||||
Long memberId = slashCommandInteractionEvent.getMember().getIdLong();
|
||||
return allowedToExecuteCommand(command, serverId, channelId, memberId);
|
||||
}
|
||||
|
||||
public CoolDownCheckResult createCooldownCheckResult(Long serverId, String commandName, Duration serverCooldown, Duration channelCooldown, Duration memberCooldown) {
|
||||
if(serverCooldown != null || channelCooldown != null || memberCooldown != null) {
|
||||
Long serverSeconds = serverCooldown != null ? serverCooldown.getSeconds() : 0L;
|
||||
@@ -393,6 +407,24 @@ public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCoolDowns(Command command, SlashCommandInteractionEvent event) {
|
||||
takeLock();
|
||||
try {
|
||||
AServerChannelUserId contextIds = AServerChannelUserId
|
||||
.builder()
|
||||
.channelId(event.getChannel().getIdLong())
|
||||
.userId(event.getMember().getIdLong())
|
||||
.guildId(event.getGuild().getIdLong())
|
||||
.build();
|
||||
addServerCoolDown(command, contextIds.getGuildId(), false);
|
||||
addChannelCoolDown(command, contextIds.toServerChannelId(), false);
|
||||
addMemberCoolDown(command, contextIds, false);
|
||||
} finally {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCoolDownConfigForChannelGroup(AChannelGroup aChannelGroup, Duration groupCoolDown, Duration memberCoolDown) {
|
||||
CoolDownChannelGroup cdChannelGroup = coolDownChannelGroupManagementService.findByChannelGroupId(aChannelGroup.getId());
|
||||
|
||||
@@ -21,7 +21,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -30,6 +33,7 @@ import org.springframework.stereotype.Component;
|
||||
public class ExceptionServiceBean implements ExceptionService {
|
||||
|
||||
public static final String MODEL_WRAPPER_TEMPLATE_KEY = "model_wrapper";
|
||||
public static final String GENERIC_INTERACTION_EXCEPTION = "generic_interaction_exception";
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@@ -68,30 +72,43 @@ public class ExceptionServiceBean implements ExceptionService {
|
||||
|
||||
@Override
|
||||
public void reportExceptionToInteraction(Throwable exception, ButtonClickedListenerModel interactionContext, ButtonClickedListener executedListener) {
|
||||
ButtonInteractionEvent event = interactionContext.getEvent();
|
||||
if(executedListener != null) {
|
||||
log.info("Reporting generic exception {} of listener {} towards channel {} in server {}.",
|
||||
exception.getClass().getSimpleName(), executedListener.getClass().getSimpleName(), interactionContext.getEvent().getChannel().getIdLong(),
|
||||
interactionContext.getEvent().getGuild().getIdLong());
|
||||
exception.getClass().getSimpleName(), executedListener.getClass().getSimpleName(), event.getChannel().getIdLong(),
|
||||
event.getGuild().getIdLong());
|
||||
} else {
|
||||
log.info("Reporting generic exception {} towards channel {} in server {}.",
|
||||
exception.getClass().getSimpleName(), interactionContext.getEvent().getChannel().getIdLong(),
|
||||
interactionContext.getEvent().getGuild().getIdLong());
|
||||
exception.getClass().getSimpleName(), event.getChannel().getIdLong(),
|
||||
event.getGuild().getIdLong());
|
||||
}
|
||||
try {
|
||||
reportGenericInteractionException(exception, interactionContext);
|
||||
reportGenericInteractionException(exception, event.getInteraction());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to notify about exception.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportSlashException(Throwable exception, SlashCommandInteractionEvent event, Command command) {
|
||||
log.info("Reporting exception of {} command {} in channel {} in guild {} from user {}.",
|
||||
exception.getClass().getSimpleName(), command.getConfiguration().getName(),
|
||||
event.getChannel().getIdLong(), event.getGuild().getIdLong(), event.getMember().getIdLong(), exception);
|
||||
reportGenericInteractionException(exception, event.getInteraction());
|
||||
}
|
||||
|
||||
private void reportGenericException(Throwable throwable, CommandContext context) {
|
||||
GenericExceptionModel exceptionModel = buildCommandModel(throwable, context);
|
||||
channelService.sendEmbedTemplateInTextChannelList("generic_command_exception", exceptionModel, context.getChannel());
|
||||
}
|
||||
|
||||
private void reportGenericInteractionException(Throwable throwable, ButtonClickedListenerModel interactionContext) {
|
||||
GenericInteractionExceptionModel exceptionModel = buildInteractionExceptionModel(throwable, interactionContext);
|
||||
interactionService.sendMessageToInteraction("generic_interaction_exception", exceptionModel, interactionContext.getEvent().getInteraction().getHook());
|
||||
private void reportGenericInteractionException(Throwable throwable, IReplyCallback replyCallback) {
|
||||
GenericInteractionExceptionModel exceptionModel = buildInteractionExceptionModel(throwable, replyCallback);
|
||||
if(replyCallback.isAcknowledged()) {
|
||||
interactionService.sendMessageToInteraction(GENERIC_INTERACTION_EXCEPTION, exceptionModel, replyCallback.getHook());
|
||||
} else {
|
||||
interactionService.replyEmbed(GENERIC_INTERACTION_EXCEPTION, exceptionModel, replyCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,16 +144,21 @@ public class ExceptionServiceBean implements ExceptionService {
|
||||
}
|
||||
}
|
||||
|
||||
private GenericInteractionExceptionModel buildInteractionExceptionModel(Throwable throwable, ButtonClickedListenerModel context) {
|
||||
private GenericInteractionExceptionModel buildInteractionExceptionModel(Throwable throwable, IReplyCallback context) {
|
||||
return GenericInteractionExceptionModel
|
||||
.builder()
|
||||
.member(context.getEvent().getMember())
|
||||
.user(context.getEvent().getUser())
|
||||
.member(context.getMember())
|
||||
.user(context.getUser())
|
||||
.throwable(throwable)
|
||||
.build();
|
||||
}
|
||||
private GenericExceptionModel buildCommandModel(Throwable throwable, CommandContext context) {
|
||||
FullUserInServer fullUser = FullUserInServer.builder().member(context.getAuthor()).aUserInAServer(userInServerManagementService.loadUserOptional(context.getGuild().getIdLong(), context.getAuthor().getIdLong()).orElse(null)).build();
|
||||
FullUserInServer fullUser = FullUserInServer
|
||||
.builder()
|
||||
.member(context.getAuthor())
|
||||
.aUserInAServer(userInServerManagementService.loadUserOptional(context.getGuild().getIdLong(), context.getAuthor().getIdLong())
|
||||
.orElse(null))
|
||||
.build();
|
||||
return GenericExceptionModel
|
||||
.builder()
|
||||
.user(fullUser)
|
||||
|
||||
@@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommandInServerManagementServiceBean implements CommandInServerManagementService {
|
||||
@@ -19,6 +21,11 @@ public class CommandInServerManagementServiceBean implements CommandInServerMana
|
||||
|
||||
@Override
|
||||
public ACommandInAServer createCommandInServer(ACommand command, AServer server) {
|
||||
return createCommandInServer(command, server, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ACommandInAServer createCommandInServer(ACommand command, AServer server, Long commandId) {
|
||||
ACommandInAServer commandInAServer = ACommandInAServer
|
||||
.builder()
|
||||
.commandReference(command)
|
||||
@@ -44,4 +51,14 @@ public class CommandInServerManagementServiceBean implements CommandInServerMana
|
||||
public ACommandInAServer getCommandForServer(ACommand command, Long serverId) {
|
||||
return repository.findByServerReference_IdAndCommandReference(serverId, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ACommandInAServer getCommandForServer(Long commandInServerId) {
|
||||
return repository.getOne(commandInServerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ACommandInAServer> getCommandsForServer(List<Long> commandInServerId) {
|
||||
return repository.findAllById(commandInServerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
package dev.sheldan.abstracto.core.command.slash;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.interactions.commands.Command;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class SlashCommandServiceBean implements SlashCommandService {
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private CommandInServerManagementService commandInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandManagementService commandManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandServiceBean self;
|
||||
|
||||
@Override
|
||||
public void convertCommandConfigToCommandData(CommandConfiguration commandConfiguration, List<Pair<List<CommandConfiguration>, SlashCommandData>> existingCommands) {
|
||||
boolean isTemplated = commandConfiguration.isTemplated();
|
||||
SlashCommandConfig slashConfig = commandConfiguration.getSlashCommandConfig();
|
||||
String description;
|
||||
String internalCommandName = commandConfiguration.getName();
|
||||
if(!isTemplated) {
|
||||
description = commandConfiguration.getDescription();
|
||||
} else {
|
||||
description = templateService.renderSimpleTemplate(internalCommandName + "_description");
|
||||
}
|
||||
String rootName = slashConfig.getSlashCompatibleRootName();
|
||||
String groupName = slashConfig.getSlashCompatibleGroupName();
|
||||
String commandName = slashConfig.getSlashCompatibleCommandName();
|
||||
Optional<SlashCommandData> existingRootCommand = existingCommands
|
||||
.stream()
|
||||
.filter(commandData -> commandData.getSecond().getName().equals(rootName))
|
||||
.map(Pair::getSecond)
|
||||
.findAny();
|
||||
SlashCommandData rootCommand = existingRootCommand.orElseGet(() -> Commands.slash(rootName, description));
|
||||
if(commandName != null) {
|
||||
SubcommandData slashCommand = new SubcommandData(commandName, description);
|
||||
if(groupName == null) {
|
||||
rootCommand.addSubcommands(slashCommand);
|
||||
} else {
|
||||
Optional<SubcommandGroupData> commandGroup = rootCommand
|
||||
.getSubcommandGroups()
|
||||
.stream()
|
||||
.filter(subcommandGroupData -> subcommandGroupData.getName().equals(groupName))
|
||||
.findAny();
|
||||
SubcommandGroupData groupData = commandGroup.orElseGet(() -> new SubcommandGroupData(groupName, description));
|
||||
groupData.addSubcommands(slashCommand);
|
||||
rootCommand.addSubcommandGroups(groupData);
|
||||
}
|
||||
List<OptionData> requiredParameters = getParameters(commandConfiguration, isTemplated, internalCommandName);
|
||||
slashCommand.addOptions(requiredParameters);
|
||||
} else {
|
||||
List<OptionData> requiredParameters = getParameters(commandConfiguration, isTemplated, internalCommandName);
|
||||
rootCommand.addOptions(requiredParameters);
|
||||
}
|
||||
if(!existingRootCommand.isPresent()) {
|
||||
Optional<Pair<List<CommandConfiguration>, SlashCommandData>> existingCommand = existingCommands
|
||||
.stream()
|
||||
.filter(listSlashCommandDataPair -> listSlashCommandDataPair.getSecond().equals(rootCommand))
|
||||
.findAny();
|
||||
if(existingCommand.isPresent()) {
|
||||
existingCommand.get().getFirst().add(commandConfiguration);
|
||||
} else {
|
||||
existingCommands.add(Pair.of(new ArrayList<>(Arrays.asList(commandConfiguration)), rootCommand));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<OptionData> getParameters(CommandConfiguration commandConfiguration, boolean isTemplated, String internalCommandName) {
|
||||
List<OptionData> requiredParameters = new ArrayList<>();
|
||||
List<OptionData> optionalParameters = new ArrayList<>();
|
||||
commandConfiguration.getParameters().forEach(parameter -> {
|
||||
List<OptionType> types = slashCommandParameterService.getTypesFromParameter(parameter.getType());
|
||||
if(types.size() > 1) {
|
||||
if(parameter.isListParam()) {
|
||||
for (int i = 0; i < parameter.getListSize(); i++) {
|
||||
for (OptionType type : types) {
|
||||
String parameterName = slashCommandParameterService.getFullQualifiedParameterName(parameter.getSlashCompatibleName(), type) + "_" + i;
|
||||
String parameterDescription = isTemplated ? templateService.renderSimpleTemplate(internalCommandName + "_parameter_" + parameter.getName()) : parameter.getDescription();
|
||||
optionalParameters.add(new OptionData(type, parameterName, parameterDescription, false));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
types.forEach(type -> {
|
||||
String parameterName = slashCommandParameterService.getFullQualifiedParameterName(parameter.getSlashCompatibleName(), type);
|
||||
String parameterDescription = isTemplated ? templateService.renderSimpleTemplate(internalCommandName + "_parameter_" + parameter.getName()) : parameter.getDescription();
|
||||
optionalParameters.add(new OptionData(type, parameterName, parameterDescription, false));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
OptionType type = types.get(0);
|
||||
String parameterDescription = isTemplated ? templateService.renderSimpleTemplate(internalCommandName + "_parameter_" + parameter.getName()) : parameter.getDescription();
|
||||
if(parameter.isListParam()) {
|
||||
for (int i = 0; i < parameter.getListSize(); i++) {
|
||||
optionalParameters.add(new OptionData(type, parameter.getSlashCompatibleName() + "_" + i, parameterDescription, false));
|
||||
}
|
||||
} else {
|
||||
if(!parameter.isOptional()) {
|
||||
requiredParameters.add(new OptionData(type, parameter.getSlashCompatibleName(), parameterDescription, true));
|
||||
} else {
|
||||
optionalParameters.add(new OptionData(type, parameter.getSlashCompatibleName(), parameterDescription, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
requiredParameters.addAll(optionalParameters);
|
||||
return requiredParameters;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Command>> updateGuildSlashCommand(Guild guild, List<Pair<List<CommandConfiguration>, SlashCommandData>> commandData) {
|
||||
List<CommandData> commands = commandData
|
||||
.stream()
|
||||
.map(Pair::getSecond)
|
||||
.collect(Collectors.toList());
|
||||
return guild.updateCommands().addCommands(commands).submit().thenApply(createdCommands -> {
|
||||
self.storeCreatedCommands(guild, commandData, createdCommands);
|
||||
return createdCommands;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteGuildSlashCommands(Guild guild, List<Long> slashCommandId, List<Long> commandInServerIds) {
|
||||
List<CompletableFuture<Void>> commandFutures = slashCommandId
|
||||
.stream()
|
||||
.map(commandI -> guild.deleteCommandById(commandI).submit())
|
||||
.collect(Collectors.toList());
|
||||
return new CompletableFutureList<>(commandFutures).getMainFuture().thenAccept(unused -> {
|
||||
self.unsetCommandInServerSlashId(commandInServerIds);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void unsetCommandInServerSlashId(List<Long> commandInServerIds) {
|
||||
List<ACommandInAServer> commandsForServer = commandInServerManagementService.getCommandsForServer(commandInServerIds);
|
||||
commandsForServer.forEach(aCommandInAServer -> aCommandInAServer.setSlashCommandId(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addGuildSlashCommands(Guild guild, List<Pair<List<CommandConfiguration>, SlashCommandData>> commandData) {
|
||||
List<CommandData> commands = commandData
|
||||
.stream()
|
||||
.map(Pair::getSecond)
|
||||
.collect(Collectors.toList());
|
||||
List<CompletableFuture<Command>> upsertFutures = commands
|
||||
.stream()
|
||||
.map(upsertCommand -> guild.upsertCommand(upsertCommand).submit())
|
||||
.collect(Collectors.toList());
|
||||
CompletableFutureList<Command> allFutures = new CompletableFutureList<>(upsertFutures);
|
||||
return allFutures.getMainFuture()
|
||||
.thenAccept(unused -> self.storeCreatedCommands(guild, commandData, allFutures.getObjects()));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void storeCreatedCommands(Guild guild, List<Pair<List<CommandConfiguration>, SlashCommandData>> commandData, List<Command> createdCommands) {
|
||||
commandData.forEach(commandConfigurationSlashCommandDataPair -> {
|
||||
SlashCommandData slashCommandData = commandConfigurationSlashCommandDataPair.getSecond();
|
||||
commandConfigurationSlashCommandDataPair.getFirst().forEach(commandConfiguration -> {
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandConfiguration.getName());
|
||||
ACommandInAServer commandInServer = commandInServerManagementService.getCommandForServer(aCommand, guild.getIdLong());
|
||||
Command createdCommand = createdCommands.stream().filter(command -> doesCommandMatch(slashCommandData, command)).findFirst().orElse(null);
|
||||
if(createdCommand != null) {
|
||||
commandInServer.setSlashCommandId(createdCommand.getIdLong());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private boolean doesCommandMatch(SlashCommandData commandConfig, Command command) {
|
||||
return commandConfig.getName().equals(command.getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@Component
|
||||
public class SlashCommandParameterServiceBean implements SlashCommandParameterService {
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private List<SlashCommandParameterProvider> parameterProviders;
|
||||
|
||||
@Override
|
||||
public <T, Z> Z getCommandOption(String name, SlashCommandInteractionEvent event, Class<T> parameterType, Class<Z> slashParameterType) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
List<OptionType> potentialOptionTypes = getTypesFromParameter(parameterType);
|
||||
OptionType actualOptionType = potentialOptionTypes.size() == 1 ? potentialOptionTypes.get(0) : null;
|
||||
if (potentialOptionTypes.size() > 1) {
|
||||
for (OptionType optionType: potentialOptionTypes) {
|
||||
if(event.getOption(getFullQualifiedParameterName(name, optionType)) != null) {
|
||||
actualOptionType = optionType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(actualOptionType == null) {
|
||||
throw new IllegalArgumentException(String.format("Could not determine option type for parameter %s", name));
|
||||
}
|
||||
if(potentialOptionTypes.size() > 1) {
|
||||
name = getFullQualifiedParameterName(name, actualOptionType);
|
||||
}
|
||||
if(actualOptionType == OptionType.BOOLEAN) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsBoolean());
|
||||
} else if (actualOptionType == OptionType.ATTACHMENT) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsAttachment());
|
||||
} else if (actualOptionType == OptionType.NUMBER) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsDouble());
|
||||
} else if(actualOptionType == OptionType.STRING) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsString());
|
||||
} else if(actualOptionType == OptionType.INTEGER) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsInt());
|
||||
} else if(actualOptionType == OptionType.ROLE) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsRole());
|
||||
} else if(actualOptionType == OptionType.MENTIONABLE) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsMentionable());
|
||||
} else if(actualOptionType == OptionType.CHANNEL) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsGuildChannel());
|
||||
} else if(actualOptionType == OptionType.USER) {
|
||||
if(parameterType.equals(User.class) && slashParameterType.equals(User.class)) {
|
||||
return slashParameterType.cast(event.getOption(name).getAsUser());
|
||||
} else {
|
||||
return slashParameterType.cast(event.getOption(name).getAsMember());
|
||||
}
|
||||
} else {
|
||||
throw new AbstractoRunTimeException("Unknown parameter type");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, Z> boolean hasCommandOption(String name, SlashCommandInteractionEvent event, Class<T> parameterType, Class<Z> slashParameterType) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
List<OptionType> potentialOptionTypes = getTypesFromParameter(parameterType);
|
||||
OptionType actualOptionType = potentialOptionTypes.size() == 1 ? potentialOptionTypes.get(0) : null;
|
||||
if (potentialOptionTypes.size() > 1) {
|
||||
for (OptionType optionType: potentialOptionTypes) {
|
||||
if(event.getOption(getFullQualifiedParameterName(name, optionType)) != null) {
|
||||
actualOptionType = optionType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(actualOptionType == null) {
|
||||
return false;
|
||||
}
|
||||
if(potentialOptionTypes.size() > 1) {
|
||||
name = getFullQualifiedParameterName(name, actualOptionType);
|
||||
}
|
||||
if(actualOptionType == OptionType.BOOLEAN) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsBoolean());
|
||||
} else if (actualOptionType == OptionType.ATTACHMENT) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsAttachment());
|
||||
} else if (actualOptionType == OptionType.NUMBER) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsDouble());
|
||||
} else if(actualOptionType == OptionType.STRING) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsString());
|
||||
} else if(actualOptionType == OptionType.INTEGER) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsInt());
|
||||
} else if(actualOptionType == OptionType.ROLE) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsRole());
|
||||
} else if(actualOptionType == OptionType.MENTIONABLE) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsMentionable());
|
||||
} else if(actualOptionType == OptionType.CHANNEL) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsGuildChannel());
|
||||
} else if(actualOptionType == OptionType.USER) {
|
||||
if (parameterType.equals(User.class) && slashParameterType.equals(User.class)) {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsUser());
|
||||
} else {
|
||||
return slashParameterType.isInstance(event.getOption(name).getAsMember());
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getCommandOption(String name, SlashCommandInteractionEvent event, Class<T> parameterType) {
|
||||
return getCommandOption(name, event, parameterType, parameterType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCommandOption(String name, SlashCommandInteractionEvent event) {
|
||||
return event.getOption(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasCommandOption(String name, SlashCommandInteractionEvent event) {
|
||||
return event.getOption(name) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasCommandOptionWithFullType(String name, SlashCommandInteractionEvent event, OptionType optionType) {
|
||||
return hasCommandOption(getFullQualifiedParameterName(name, optionType), event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AEmote loadAEmoteFromString(String input, SlashCommandInteractionEvent event) {
|
||||
Emoji emoji = loadEmoteFromString(input, event);
|
||||
return emoteService.getFakeEmoteFromEmoji(emoji);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Emoji loadEmoteFromString(String input, SlashCommandInteractionEvent event) {
|
||||
if(StringUtils.isNumeric(input)) {
|
||||
long emoteId = Long.parseLong(input);
|
||||
return Emoji.fromEmote(event.getGuild().getEmoteById(emoteId));
|
||||
}
|
||||
return Emoji.fromMarkdown(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OptionType> getTypesFromParameter(Class clazz) {
|
||||
return parameterProviders
|
||||
.stream()
|
||||
.filter(slashCommandParameterProvider -> slashCommandParameterProvider.getOptionMapping().getType().equals(clazz))
|
||||
.findAny()
|
||||
.map(slashCommandParameterProvider -> slashCommandParameterProvider.getOptionMapping().getOptionTypes())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format("Unknown type for slash command parameter desired %s", clazz.getName())));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getFullQualifiedParameterName(String name, OptionType type) {
|
||||
switch (type) {
|
||||
case STRING:
|
||||
return name + "_string";
|
||||
case INTEGER:
|
||||
return name + "_integer";
|
||||
case BOOLEAN:
|
||||
return name + "_boolean";
|
||||
case USER:
|
||||
return name + "_user";
|
||||
case CHANNEL:
|
||||
return name + "_channel";
|
||||
case ROLE:
|
||||
return name + "_role";
|
||||
case MENTIONABLE:
|
||||
return name + "_mentionable";
|
||||
case NUMBER:
|
||||
return name + "_number";
|
||||
case ATTACHMENT:
|
||||
return name + "_attachment";
|
||||
default: throw new IllegalArgumentException(String.format("Not supported parameter type %s", type));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class AChannelSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(AChannel.class)
|
||||
.optionTypes(Arrays.asList(OptionType.CHANNEL, OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class AEmoteSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(AEmote.class)
|
||||
.optionTypes(Arrays.asList(OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class ARoleSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(ARole.class)
|
||||
.optionTypes(Arrays.asList(OptionType.ROLE, OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class BooleanSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Boolean.class)
|
||||
.optionTypes(Arrays.asList(OptionType.BOOLEAN))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import dev.sheldan.abstracto.core.models.database.ChannelGroupType;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class ChannelGroupTypeSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(ChannelGroupType.class)
|
||||
.optionTypes(Arrays.asList(OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class DoubleSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Double.class)
|
||||
.optionTypes(Arrays.asList(OptionType.NUMBER))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class DurationSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Duration.class)
|
||||
.optionTypes(Arrays.asList(OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class EmoteSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Emote.class)
|
||||
.optionTypes(Arrays.asList(OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class FileSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(File.class)
|
||||
.optionTypes(Arrays.asList(OptionType.ATTACHMENT))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class GuildChannelSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(GuildChannel.class)
|
||||
.optionTypes(Arrays.asList(OptionType.CHANNEL))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class GuildMessageChannelSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(GuildMessageChannel.class)
|
||||
.optionTypes(Arrays.asList(OptionType.CHANNEL))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class InstantSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Instant.class)
|
||||
.optionTypes(Arrays.asList(OptionType.INTEGER))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class IntegerSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Integer.class)
|
||||
.optionTypes(Arrays.asList(OptionType.INTEGER))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class LongSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Long.class)
|
||||
.optionTypes(Arrays.asList(OptionType.INTEGER))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class MemberSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Member.class)
|
||||
.optionTypes(Arrays.asList(OptionType.USER))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class RoleSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(Role.class)
|
||||
.optionTypes(Arrays.asList(OptionType.ROLE))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class StringSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(String.class)
|
||||
.optionTypes(Arrays.asList(OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class TextChannelSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(TextChannel.class)
|
||||
.optionTypes(Arrays.asList(OptionType.CHANNEL))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.slash.parameter.provider.provided;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandOptionTypeMapping;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.provider.SlashCommandParameterProvider;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Component
|
||||
public class UserSlashCommandParameterProvider implements SlashCommandParameterProvider {
|
||||
@Override
|
||||
public SlashCommandOptionTypeMapping getOptionMapping() {
|
||||
return SlashCommandOptionTypeMapping
|
||||
.builder()
|
||||
.type(User.class)
|
||||
.optionTypes(Arrays.asList(OptionType.USER, OptionType.STRING))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,47 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class AddToChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
|
||||
public static final String ADD_TO_CHANNEL_GROUP_COMMAND = "addToChannelGroup";
|
||||
public static final String CHANNEL_PARAMETER = "channel";
|
||||
public static final String NAME_PARAMETER = "name";
|
||||
private static final String ADD_TO_CHANNEL_GROUP_RESPONSE_TEMPLATE = "addToChannelGroup_response";
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String name = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -35,18 +53,53 @@ public class AddToChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
GuildChannel channel = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, TextChannel.class, GuildChannel.class);
|
||||
if(!channel.getGuild().equals(event.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
channelGroupService.addChannelToChannelGroup(channelGroupName, channel);
|
||||
return interactionService.replyEmbed(ADD_TO_CHANNEL_GROUP_RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter channelToAdd = Parameter.builder().name("channel").type(TextChannel.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter channelToAdd = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_PARAMETER)
|
||||
.type(TextChannel.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelToAdd);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
List<String> aliases = Arrays.asList("addTChGrp", "chGrpCh+");
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(ADD_TO_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("addToChannelGroup")
|
||||
.name(ADD_TO_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.aliases(aliases)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,31 +1,48 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.ChannelGroupType;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupTypeManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class CreateChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CREATE_CHANNEL_GROUP_COMMAND = "createChannelGroup";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String GROUP_TYPE_PARAMETER = "groupType";
|
||||
private static final String CREATE_CHANNEL_GROUP_RESPONSE_TEMPLATE = "createChannelGroup_response";
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupTypeManagementService channelGroupTypeManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -36,18 +53,51 @@ public class CreateChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
String channelGroupType = slashCommandParameterService.getCommandOption(GROUP_TYPE_PARAMETER, event, ChannelGroupType.class, String.class);
|
||||
|
||||
ChannelGroupType actualGroupType = channelGroupTypeManagementService.findChannelGroupTypeByKey((channelGroupType).trim());
|
||||
channelGroupService.createChannelGroup(channelGroupName, event.getGuild().getIdLong(), actualGroupType);
|
||||
return interactionService.replyEmbed(CREATE_CHANNEL_GROUP_RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter channelGroupType = Parameter.builder().name("groupType").type(ChannelGroupType.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter channelGroupType = Parameter
|
||||
.builder()
|
||||
.name(GROUP_TYPE_PARAMETER)
|
||||
.type(ChannelGroupType.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(CREATE_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelGroupType);
|
||||
List<String> aliases = Arrays.asList("+ChGroup");
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("createChannelGroup")
|
||||
.name(CREATE_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.aliases(aliases)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class DeleteChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String DELETE_CHANNEL_GROUP_COMMAND = "deleteChannelGroup";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String DELETE_CHANNEL_GROUP_RESPONSE = "deleteChannelGroup_response";
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String groupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -28,17 +44,42 @@ public class DeleteChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
channelGroupService.deleteChannelGroup(channelGroupName, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(DELETE_CHANNEL_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName);
|
||||
List<String> aliases = Arrays.asList("-ChGroup");
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(DELETE_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("deleteChannelGroup")
|
||||
.name(DELETE_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.aliases(aliases)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,23 +1,39 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class DisableChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CHANNEL_GROUP_NAME_PARAMETER = "channelGroupName";
|
||||
private static final String DISABLE_CHANNEL_GROUP_COMMAND = "disableChannelGroup";
|
||||
private static final String DISABLE_CHANNEL_GROUP_RESPONSE = "disableChannelGroup_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@@ -28,15 +44,40 @@ public class DisableChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(CHANNEL_GROUP_NAME_PARAMETER, event, String.class);
|
||||
channelGroupService.disableChannelGroup(channelGroupName, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(DISABLE_CHANNEL_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_GROUP_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(DISABLE_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("disableChannelGroup")
|
||||
.name(DISABLE_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.PostTargetNotValidException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class DisablePostTarget extends AbstractConditionableCommand {
|
||||
|
||||
private static final String DISABLE_POSTTARGET_COMMAND = "disablePosttarget";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String DISABLE_POST_TARGET_RESPONSE = "disablePosttarget_response";
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String targetName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -32,11 +48,22 @@ public class DisablePostTarget extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String postTargetName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
if(!postTargetService.validPostTarget(postTargetName)) {
|
||||
throw new PostTargetNotValidException(postTargetName, postTargetService.getAvailablePostTargets());
|
||||
}
|
||||
postTargetService.disablePostTarget(postTargetName, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(DISABLE_POST_TARGET_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter postTargetName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
@@ -45,10 +72,19 @@ public class DisablePostTarget extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.POST_TARGET)
|
||||
.commandName("disable")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("disablePosttarget")
|
||||
.name(DISABLE_POSTTARGET_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class EnableChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CHANNEL_GROUP_NAME_PARAMETER = "channelGroupName";
|
||||
private static final String ENABLE_CHANNEL_GROUP_COMMAND = "enableChannelGroup";
|
||||
private static final String ENABLE_CHANNEL_GROUP_RESPONSE = "enableChannelGroup_response";
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -28,15 +44,40 @@ public class EnableChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(CHANNEL_GROUP_NAME_PARAMETER, event, String.class);
|
||||
channelGroupService.enableChannelGroup(channelGroupName, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(ENABLE_CHANNEL_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_GROUP_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(ENABLE_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("enableChannelGroup")
|
||||
.name(ENABLE_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.PostTargetNotValidException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class EnablePostTarget extends AbstractConditionableCommand {
|
||||
|
||||
private static final String ENABLE_POSTTARGET_COMMAND = "enablePosttarget";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String ENABLE_POSTTARGET_RESPONSE = "enablePosttarget_response";
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String targetName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -32,11 +48,22 @@ public class EnablePostTarget extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String postTargetName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
if(!postTargetService.validPostTarget(postTargetName)) {
|
||||
throw new PostTargetNotValidException(postTargetName, postTargetService.getAvailablePostTargets());
|
||||
}
|
||||
postTargetService.enablePostTarget(postTargetName, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(ENABLE_POSTTARGET_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter postTargetName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
@@ -45,10 +72,19 @@ public class EnablePostTarget extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.POST_TARGET)
|
||||
.commandName("enable")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("enablePosttarget")
|
||||
.name(ENABLE_POSTTARGET_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ListChannelGroupsModel;
|
||||
@@ -17,15 +19,19 @@ import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementServi
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class ListChannelGroups extends AbstractConditionableCommand {
|
||||
|
||||
public static final String LIST_CHANNEL_GROUPS_COMMAND = "listChannelGroups";
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@@ -41,24 +47,52 @@ public class ListChannelGroups extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
List<AChannelGroup> channelGroups = channelGroupManagementService.findAllInServer(server);
|
||||
ListChannelGroupsModel template = (ListChannelGroupsModel) ContextConverter.fromCommandContext(commandContext, ListChannelGroupsModel.class);
|
||||
template.setGroups(channelGroupService.convertAChannelGroupToChannelGroupChannel(channelGroups));
|
||||
MessageToSend response = templateService.renderEmbedTemplate("listChannelGroups_response", template, commandContext.getGuild().getIdLong());
|
||||
MessageToSend response = getMessageToSend(commandContext.getGuild());
|
||||
channelService.sendMessageToSendToChannel(response, commandContext.getChannel());
|
||||
return CommandResult.fromIgnored();
|
||||
}
|
||||
|
||||
private MessageToSend getMessageToSend(Guild guild) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
List<AChannelGroup> channelGroups = channelGroupManagementService.findAllInServer(server);
|
||||
ListChannelGroupsModel template = ListChannelGroupsModel
|
||||
.builder()
|
||||
.groups(channelGroupService.convertAChannelGroupToChannelGroupChannel(channelGroups))
|
||||
.build();
|
||||
return templateService.renderEmbedTemplate("listChannelGroups_response", template, guild.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
MessageToSend response = getMessageToSend(event.getGuild());
|
||||
return interactionService.replyMessageToSend(response, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<String> aliases = Arrays.asList("lsChGrp");
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(LIST_CHANNEL_GROUPS_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("listChannelGroups")
|
||||
.name(LIST_CHANNEL_GROUPS_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.aliases(aliases)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.exception.PostTargetNotValidException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.PostTarget;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.PostTargetDisplayModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.PostTargetModelEntry;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -35,7 +42,11 @@ import java.util.concurrent.CompletableFuture;
|
||||
@Slf4j
|
||||
public class PostTargetCommand extends AbstractConditionableCommand {
|
||||
|
||||
public static final String POST_TARGET_SHOW_TARGETS = "posttarget_show_targets";
|
||||
private static final String POST_TARGET_SHOW_TARGETS = "posttarget_show_targets";
|
||||
private static final String POSTTARGET_COMMAND = "posttarget";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String CHANNEL_PARAMETER = "channel";
|
||||
private static final String POSTTARGET_RESPONSE_TEMPLATE = "posttarget_response";
|
||||
|
||||
@Autowired
|
||||
private PostTargetManagement postTargetManagement;
|
||||
@@ -49,66 +60,133 @@ public class PostTargetCommand extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
Guild guild = commandContext.getGuild();
|
||||
if(commandContext.getParameters().getParameters().isEmpty()) {
|
||||
log.debug("Displaying existing post targets for guild {}.", commandContext.getGuild().getId());
|
||||
PostTargetDisplayModel posttargetDisplayModel = (PostTargetDisplayModel) ContextConverter.fromCommandContext(commandContext, PostTargetDisplayModel.class);
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
List<PostTarget> postTargets = postTargetService.getPostTargets(server);
|
||||
posttargetDisplayModel.setPostTargets(new ArrayList<>());
|
||||
List<PostTargetModelEntry> postTargetEntries = posttargetDisplayModel.getPostTargets();
|
||||
postTargets.forEach(target -> {
|
||||
Optional<GuildMessageChannel> channelFromAChannel = channelService.getGuildMessageChannelFromAChannelOptional(target.getChannelReference());
|
||||
PostTargetModelEntry targetEntry = PostTargetModelEntry
|
||||
.builder()
|
||||
.channel(channelFromAChannel.orElse(null))
|
||||
.disabled(target.getDisabled())
|
||||
.postTarget(target).build();
|
||||
postTargetEntries.add(targetEntry);
|
||||
});
|
||||
List<String> postTargetConfigs = postTargetService.getPostTargetsOfEnabledFeatures(server);
|
||||
postTargetConfigs.forEach(postTargetName -> {
|
||||
if(postTargetEntries.stream().noneMatch(postTargetModelEntry -> postTargetModelEntry.getPostTarget().getName().equalsIgnoreCase(postTargetName))) {
|
||||
PostTarget fakeEntry = PostTarget
|
||||
.builder()
|
||||
.name(postTargetName)
|
||||
.build();
|
||||
PostTargetModelEntry postTargetEntry = PostTargetModelEntry
|
||||
.builder()
|
||||
.postTarget(fakeEntry)
|
||||
.disabled(false)
|
||||
.build();
|
||||
postTargetEntries.add(postTargetEntry);
|
||||
}
|
||||
});
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(POST_TARGET_SHOW_TARGETS, posttargetDisplayModel, commandContext.getChannel()))
|
||||
log.debug("Displaying existing post targets for guild {}.", guild.getId());
|
||||
MessageToSend messageToSend = getMessageToSendForPosttargetDisplay(guild);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
String targetName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
GuildChannel channel = (GuildChannel) commandContext.getParameters().getParameters().get(1);
|
||||
validateAndCreatePosttarget(guild, targetName, channel);
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private void validateAndCreatePosttarget(Guild guild, String targetName, GuildChannel channel) {
|
||||
if(!postTargetService.validPostTarget(targetName)) {
|
||||
throw new PostTargetNotValidException(targetName, postTargetService.getAvailablePostTargets());
|
||||
}
|
||||
GuildChannel channel = (GuildChannel) commandContext.getParameters().getParameters().get(1);
|
||||
if(!channel.getGuild().equals(commandContext.getGuild())) {
|
||||
if(!channel.getGuild().equals(guild)) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
Guild guild = channel.getGuild();
|
||||
postTargetManagement.createOrUpdate(targetName, guild.getIdLong(), channel.getIdLong());
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private MessageToSend getMessageToSendForPosttargetDisplay(Guild guild) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
List<PostTarget> postTargets = postTargetService.getPostTargets(server);
|
||||
ArrayList<PostTargetModelEntry> postTargetEntries = new ArrayList<>();
|
||||
postTargets.forEach(target -> {
|
||||
Optional<GuildMessageChannel> channelFromAChannel = channelService.getGuildMessageChannelFromAChannelOptional(target.getChannelReference());
|
||||
PostTargetModelEntry targetEntry = PostTargetModelEntry
|
||||
.builder()
|
||||
.channel(channelFromAChannel.orElse(null))
|
||||
.disabled(target.getDisabled())
|
||||
.postTarget(target).build();
|
||||
postTargetEntries.add(targetEntry);
|
||||
});
|
||||
PostTargetDisplayModel posttargetDisplayModel = PostTargetDisplayModel
|
||||
.builder()
|
||||
.postTargets(postTargetEntries)
|
||||
.build();
|
||||
|
||||
List<String> postTargetConfigs = postTargetService.getPostTargetsOfEnabledFeatures(server);
|
||||
postTargetConfigs.forEach(postTargetName -> {
|
||||
if(postTargetEntries.stream().noneMatch(postTargetModelEntry -> postTargetModelEntry.getPostTarget().getName().equalsIgnoreCase(postTargetName))) {
|
||||
PostTarget fakeEntry = PostTarget
|
||||
.builder()
|
||||
.name(postTargetName)
|
||||
.build();
|
||||
PostTargetModelEntry postTargetEntry = PostTargetModelEntry
|
||||
.builder()
|
||||
.postTarget(fakeEntry)
|
||||
.disabled(false)
|
||||
.build();
|
||||
postTargetEntries.add(postTargetEntry);
|
||||
}
|
||||
});
|
||||
return templateService.renderEmbedTemplate(POST_TARGET_SHOW_TARGETS, posttargetDisplayModel, guild.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
if(!slashCommandParameterService.hasCommandOption(CHANNEL_PARAMETER, event) && !slashCommandParameterService.hasCommandOption(NAME_PARAMETER, event)) {
|
||||
MessageToSend messageToSend = getMessageToSendForPosttargetDisplay(event.getGuild());
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
if(!slashCommandParameterService.hasCommandOption(NAME_PARAMETER, event)) {
|
||||
throw new SlashCommandParameterMissingException(NAME_PARAMETER);
|
||||
}
|
||||
if(!slashCommandParameterService.hasCommandOption(CHANNEL_PARAMETER, event)) {
|
||||
throw new SlashCommandParameterMissingException(CHANNEL_PARAMETER);
|
||||
}
|
||||
String postTargetName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
GuildChannel channel = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, TextChannel.class, GuildChannel.class);
|
||||
validateAndCreatePosttarget(event.getGuild(), postTargetName, channel);
|
||||
return interactionService.replyEmbed(POSTTARGET_RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter postTargetName = Parameter.builder().name("name").type(String.class).optional(true).templated(true).build();
|
||||
Parameter channel = Parameter.builder().name("channel").type(TextChannel.class).optional(true).templated(true).build();
|
||||
Parameter postTargetName = Parameter
|
||||
.builder()
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter channel = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_PARAMETER)
|
||||
.type(TextChannel.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(postTargetName, channel);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.POST_TARGET)
|
||||
.commandName(POSTTARGET_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("posttarget")
|
||||
.name(POSTTARGET_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,32 +1,51 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class RemoveFromChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String REMOVE_FROM_CHANNEL_GROUP_COMMAND = "removeFromChannelGroup";
|
||||
private static final String CHANNEL_PARAMETER = "channel";
|
||||
private static final String NAME_PARAMETER = "name";
|
||||
private static final String REMOVE_FROM_CHANNEL_GROUP_RESPONSE = "removeFromChannelGroup_response";
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String name = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -39,18 +58,57 @@ public class RemoveFromChannelGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String channelGroupName = slashCommandParameterService.getCommandOption(NAME_PARAMETER, event, String.class);
|
||||
AChannel actualChannel;
|
||||
if(slashCommandParameterService.hasCommandOptionWithFullType(CHANNEL_PARAMETER, event, OptionType.CHANNEL)) {
|
||||
GuildMessageChannel guildChannel = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, AChannel.class, GuildMessageChannel.class);
|
||||
actualChannel = channelManagementService.loadChannel(guildChannel.getIdLong());
|
||||
} else if(slashCommandParameterService.hasCommandOptionWithFullType(CHANNEL_PARAMETER, event, OptionType.STRING)) {
|
||||
String channelId = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, AChannel.class, String.class);
|
||||
actualChannel = channelManagementService.loadChannel(Long.parseLong(channelId));
|
||||
} else {
|
||||
throw new SlashCommandParameterMissingException(CHANNEL_PARAMETER);
|
||||
}
|
||||
channelGroupService.removeChannelFromChannelGroup(channelGroupName, actualChannel);
|
||||
return interactionService.replyEmbed(REMOVE_FROM_CHANNEL_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("name").type(String.class).build();
|
||||
Parameter channelToAdd = Parameter.builder().name("channel").type(AChannel.class).build();
|
||||
Parameter channelGroupName = Parameter
|
||||
.builder()
|
||||
.name(NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
Parameter channelToAdd = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_PARAMETER)
|
||||
.type(AChannel.class)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelToAdd);
|
||||
List<String> aliases = Arrays.asList("rmChChgrp", "chGrpCh-");
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CHANNELS)
|
||||
.commandName(REMOVE_FROM_CHANNEL_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("removeFromChannelGroup")
|
||||
.name(REMOVE_FROM_CHANNEL_GROUP_COMMAND)
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.aliases(aliases)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
.supportsEmbedException(true)
|
||||
|
||||
@@ -1,40 +1,71 @@
|
||||
package dev.sheldan.abstracto.core.commands.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.CacheServiceBean;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class ClearCache extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CLEAR_CACHE_COMMAND = "clearCache";
|
||||
private static final String RESPONSE_TEMPLATE = "clearCache_response";
|
||||
|
||||
@Autowired
|
||||
private CacheServiceBean cacheServiceBean;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
cacheServiceBean.clearCaches();
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
cacheServiceBean.clearCaches();
|
||||
return interactionService.replyEmbed(RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INTERNAL)
|
||||
.commandName(CLEAR_CACHE_COMMAND)
|
||||
.build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("clearCache")
|
||||
.name(CLEAR_CACHE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
package dev.sheldan.abstracto.core.commands.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.ConfigurationKeyNotFoundException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -31,6 +36,16 @@ public class ResetConfig extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private FeatureManagementService featureManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String RESPONSE_TEMPLATE = "resetConfig_response";
|
||||
private static final String KEY_PARAMETER = "key";
|
||||
private static final String RESET_CONFIG_COMMAND = "resetConfig";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
Long serverId = commandContext.getGuild().getIdLong();
|
||||
@@ -49,16 +64,53 @@ public class ResetConfig extends AbstractConditionableCommand {
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
long serverId = event.getGuild().getIdLong();
|
||||
if(!slashCommandParameterService.hasCommandOption("key", event)) {
|
||||
configService.resetConfigForServer(serverId);
|
||||
} else {
|
||||
String key = slashCommandParameterService.getCommandOption(KEY_PARAMETER, event, String.class);
|
||||
if(featureManagementService.featureExists(key)) {
|
||||
configService.resetConfigForFeature(key, serverId);
|
||||
} else if(defaultConfigManagementService.configKeyExists(key)) {
|
||||
configService.resetConfigForKey(key, serverId);
|
||||
} else {
|
||||
throw new ConfigurationKeyNotFoundException(key);
|
||||
}
|
||||
}
|
||||
return interactionService.replyEmbed(RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter keyToChange = Parameter.builder().name("key").type(String.class).optional(true).templated(true).build();
|
||||
Parameter keyToChange = Parameter
|
||||
.builder()
|
||||
.name("key")
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(keyToChange);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName("reset")
|
||||
.build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("resetConfig")
|
||||
.name(RESET_CONFIG_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class SetConfig extends AbstractConditionableCommand {
|
||||
|
||||
private static final String KEY_PARAMETER = "key";
|
||||
private static final String VALUE_PARAMETER = "value";
|
||||
private static final String SET_CONFIG_COMMAND = "setConfig";
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String RESPONSE_TEMPLATE = "setConfig_response";
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String key = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -30,16 +47,48 @@ public class SetConfig extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String key = slashCommandParameterService.getCommandOption(KEY_PARAMETER, event, String.class);
|
||||
String value = slashCommandParameterService.getCommandOption(VALUE_PARAMETER, event, String.class);
|
||||
configService.setOrCreateConfigValue(key, event.getGuild().getIdLong(), value);
|
||||
return interactionService.replyEmbed(RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter keyToChange = Parameter.builder().name("key").type(String.class).templated(true).build();
|
||||
Parameter valueToSet = Parameter.builder().name("value").type(String.class).templated(true).build();
|
||||
Parameter keyToChange = Parameter
|
||||
.builder()
|
||||
.name(KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter valueToSet = Parameter
|
||||
.builder()
|
||||
.name(VALUE_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(keyToChange, valueToSet);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName("set")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("setConfig")
|
||||
.name(SET_CONFIG_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -16,7 +16,6 @@ import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeature;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -37,9 +36,6 @@ public class Allow extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.FeatureSwitchModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -33,6 +37,7 @@ import java.util.stream.Collectors;
|
||||
@Component
|
||||
public class DisableFeature extends AbstractConditionableCommand {
|
||||
|
||||
public static final String DISABLE_FEATURE_COMMAND = "disableFeature";
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@@ -47,61 +52,114 @@ public class DisableFeature extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
private static final String DISABLE_FEATURE_ALL_FEATURES_RESPONSE_TEMPLATE_KEY = "disableFeature_all_features_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String DISABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY = "disableFeature_feature_dependencies_response";
|
||||
private static final String DISABLE_FEATURE_RESPONSE_TEMPLATE_KEY = "disableFeature_response";
|
||||
private static final String FEATURE_NAME_PARAMETER = "featureName";
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
if (commandContext.getParameters().getParameters().isEmpty()) {
|
||||
FeatureSwitchModel model = (FeatureSwitchModel) ContextConverter.fromCommandContext(commandContext, FeatureSwitchModel.class);
|
||||
model.setFeatures(featureConfigService.getAllFeatures());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DISABLE_FEATURE_ALL_FEATURES_RESPONSE_TEMPLATE_KEY, model, commandContext.getGuild().getIdLong());
|
||||
String flagKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(flagKey);
|
||||
Long serverId = commandContext.getGuild().getIdLong();
|
||||
List<FeatureConfig> featureDependencies = disableFeature(feature, serverId);
|
||||
if (featureDependencies.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = FeatureSwitchModel
|
||||
.builder()
|
||||
.features(additionalFeatures)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DISABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(message -> CommandResult.fromIgnored());
|
||||
} else {
|
||||
String flagKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(flagKey);
|
||||
featureFlagService.disableFeature(feature, commandContext.getGuild().getIdLong());
|
||||
List<FeatureConfig> featureDependencies = new ArrayList<>();
|
||||
if (feature.getDependantFeatures() != null) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
feature.getDependantFeatures().forEach(featureDisplay -> {
|
||||
if (featureFlagService.isFeatureEnabled(featureDisplay, server)) {
|
||||
featureFlagService.disableFeature(featureDisplay, server);
|
||||
featureDependencies.add(featureDisplay);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
if (featureDependencies.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = (FeatureSwitchModel) ContextConverter.fromCommandContext(commandContext, FeatureSwitchModel.class);
|
||||
model.setFeatures(additionalFeatures);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DISABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(message -> CommandResult.fromIgnored());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String featureName = slashCommandParameterService.getCommandOption(FEATURE_NAME_PARAMETER, event, String.class);
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(featureName);
|
||||
Long serverId = event.getGuild().getIdLong();
|
||||
List<FeatureConfig> featureDependencies = disableFeature(feature, serverId);
|
||||
if (featureDependencies.isEmpty()) {
|
||||
return interactionService.replyEmbed(DISABLE_FEATURE_RESPONSE_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = FeatureSwitchModel
|
||||
.builder()
|
||||
.features(additionalFeatures)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DISABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, serverId);
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
private List<FeatureConfig> disableFeature(FeatureConfig feature, Long serverId) {
|
||||
featureFlagService.disableFeature(feature, serverId);
|
||||
List<FeatureConfig> featureDependencies = new ArrayList<>();
|
||||
if (feature.getDependantFeatures() != null) {
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
feature.getDependantFeatures().forEach(featureDisplay -> {
|
||||
if (featureFlagService.isFeatureEnabled(featureDisplay, server)) {
|
||||
featureFlagService.disableFeature(featureDisplay, server);
|
||||
featureDependencies.add(featureDisplay);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return featureDependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("featureName").templated(true).type(String.class).optional(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(FEATURE_NAME_PARAMETER)
|
||||
.templated(true)
|
||||
.type(String.class)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(featureName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName("disable")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("disableFeature")
|
||||
.name(DISABLE_FEATURE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.async(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.management.FeatureModeManagementService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class DisableMode extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FeatureManagementService featureManagementService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@@ -35,10 +36,18 @@ public class DisableMode extends AbstractConditionableCommand {
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeManagementService featureModeManagementService;
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String DISABLE_MODE_RESPONSE_KEY = "disableMode_response";
|
||||
private static final String FEATURE_PARAMETER = "feature";
|
||||
private static final String MODE_PARAMETER = "mode";
|
||||
private static final String DISABLE_MODE_COMMAND = "disableMode";
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
@@ -51,17 +60,53 @@ public class DisableMode extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String featureName = slashCommandParameterService.getCommandOption(FEATURE_PARAMETER, event, String.class);
|
||||
String modeName = slashCommandParameterService.getCommandOption(MODE_PARAMETER, event, String.class);
|
||||
FeatureDefinition featureDefinition = featureConfigService.getFeatureEnum(featureName);
|
||||
FeatureMode featureMode = featureModeService.getFeatureModeForKey(featureName, modeName);
|
||||
AServer server = serverManagementService.loadServer(event.getGuild());
|
||||
featureModeService.disableFeatureModeForFeature(featureDefinition, server, featureMode);
|
||||
return interactionService.replyEmbed(DISABLE_MODE_RESPONSE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("feature").type(String.class).templated(true).build();
|
||||
Parameter mode = Parameter.builder().name("mode").type(String.class).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(FEATURE_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter mode = Parameter
|
||||
.builder()
|
||||
.name(MODE_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(featureName, mode);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName(DISABLE_MODE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("disableMode")
|
||||
.name(DISABLE_MODE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.FeatureValidationResult;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.FeatureSwitchModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -51,65 +55,119 @@ public class EnableFeature extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String ENABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY = "enableFeature_feature_dependencies_response";
|
||||
private static final String ENABLE_FEATURE_ALL_FEATURES_RESPONSE = "enableFeature_all_features_response";
|
||||
private static final String ENABLE_FEATURE_RESPONSE_TEMPLATE_KEY = "enableFeature_response";
|
||||
private static final String FEATURE_NAME_PARAMETER = "featureName";
|
||||
private static final String ENABLE_FEATURE_COMMAND = "enableFeature";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
if(commandContext.getParameters().getParameters().isEmpty()) {
|
||||
FeatureSwitchModel model = (FeatureSwitchModel) ContextConverter.fromCommandContext(commandContext, FeatureSwitchModel.class);
|
||||
model.setFeatures(featureConfigService.getAllFeatures());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ENABLE_FEATURE_ALL_FEATURES_RESPONSE, model, commandContext.getGuild().getIdLong());
|
||||
Long serverId = commandContext.getGuild().getIdLong();
|
||||
String featureKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
EnableFeatureResult result = enableFeature(serverId, featureKey);
|
||||
|
||||
if(result.featureDependencies.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = result.featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = FeatureSwitchModel
|
||||
.builder()
|
||||
.features(additionalFeatures)
|
||||
.validationText(result.validationResult.getValidationText())
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ENABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(message -> CommandResult.fromIgnored());
|
||||
} else {
|
||||
String featureKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(featureKey);
|
||||
AServer server = serverManagementService.loadServer(commandContext.getUserInitiatedContext().getGuild().getIdLong());
|
||||
FeatureValidationResult featureSetup = featureConfigService.validateFeatureSetup(feature, server);
|
||||
if(Boolean.FALSE.equals(featureSetup.getValidationResult())) {
|
||||
log.info("Feature {} has failed the setup validation. Notifying user.", featureKey);
|
||||
channelService.sendTextToChannelNotAsync(templateService.renderTemplatable(featureSetup, commandContext.getGuild().getIdLong()),
|
||||
commandContext.getChannel());
|
||||
}
|
||||
featureFlagService.enableFeature(feature, server);
|
||||
List<FeatureConfig> featureDependencies = new ArrayList<>();
|
||||
if(feature.getRequiredFeatures() != null) {
|
||||
feature.getRequiredFeatures().forEach(featureDisplay -> {
|
||||
log.info("Also enabling required feature {}.", featureDisplay.getFeature().getKey());
|
||||
if(!featureFlagService.isFeatureEnabled(featureDisplay, server)) {
|
||||
featureFlagService.enableFeature(featureDisplay, server);
|
||||
featureDependencies.add(featureDisplay);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(featureDependencies.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = (FeatureSwitchModel) ContextConverter.fromCommandContext(commandContext, FeatureSwitchModel.class);
|
||||
model.setFeatures(additionalFeatures);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ENABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(message -> CommandResult.fromIgnored());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String featureName = slashCommandParameterService.getCommandOption(FEATURE_NAME_PARAMETER, event, String.class);
|
||||
EnableFeatureResult enableFeatureResult = enableFeature(event.getGuild().getIdLong(), featureName);
|
||||
if(enableFeatureResult.featureDependencies.isEmpty()) {
|
||||
return interactionService.replyEmbed(ENABLE_FEATURE_RESPONSE_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
List<String> additionalFeatures = enableFeatureResult.featureDependencies
|
||||
.stream()
|
||||
.map(featureDef -> featureDef.getFeature().getKey()).
|
||||
collect(Collectors.toList());
|
||||
FeatureSwitchModel model = FeatureSwitchModel
|
||||
.builder()
|
||||
.validationText(enableFeatureResult.validationResult.getValidationText())
|
||||
.features(additionalFeatures)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ENABLE_FEATURE_DEPENDENCIES_RESPONSE_TEMPLATE_KEY,
|
||||
model, event.getGuild().getIdLong());
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
private EnableFeatureResult enableFeature(Long serverId, String featureKey) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(featureKey);
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
FeatureValidationResult validationResult = featureConfigService.validateFeatureSetup(feature, server);
|
||||
if(Boolean.FALSE.equals(validationResult.getValidationResult())) {
|
||||
log.info("Feature {} has failed the setup validation. Notifying user.", featureKey);
|
||||
validationResult.setValidationText(templateService.renderTemplatable(validationResult, serverId));
|
||||
}
|
||||
featureFlagService.enableFeature(feature, server);
|
||||
List<FeatureConfig> featureDependencies = new ArrayList<>();
|
||||
if(feature.getRequiredFeatures() != null) {
|
||||
feature.getRequiredFeatures().forEach(featureDisplay -> {
|
||||
log.info("Also enabling required feature {}.", featureDisplay.getFeature().getKey());
|
||||
if(!featureFlagService.isFeatureEnabled(featureDisplay, server)) {
|
||||
featureFlagService.enableFeature(featureDisplay, server);
|
||||
featureDependencies.add(featureDisplay);
|
||||
}
|
||||
});
|
||||
}
|
||||
EnableFeatureResult result = new EnableFeatureResult();
|
||||
result.featureDependencies = featureDependencies;
|
||||
result.validationResult = validationResult;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("featureName").type(String.class).optional(true).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(FEATURE_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(featureName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName("enable")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("enableFeature")
|
||||
.name(ENABLE_FEATURE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
@@ -128,4 +186,9 @@ public class EnableFeature extends AbstractConditionableCommand {
|
||||
conditions.remove(featureEnabledCondition);
|
||||
return conditions;
|
||||
}
|
||||
|
||||
private static class EnableFeatureResult {
|
||||
private FeatureValidationResult validationResult;
|
||||
private List<FeatureConfig> featureDependencies;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.management.FeatureModeManagementService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class EnableMode extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private FeatureManagementService featureManagementService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@@ -35,11 +36,19 @@ public class EnableMode extends AbstractConditionableCommand {
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeManagementService featureModeManagementService;
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
private static final String ENABLE_MODE_RESPONSE_KEY = "enableMode_response";
|
||||
private static final String FEATURE_PARAMETER = "feature";
|
||||
private static final String MODE_PARAMETER = "mode";
|
||||
private static final String ENABLE_MODE_COMMAND = "enableMode";
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String featureName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -51,17 +60,51 @@ public class EnableMode extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String featureName = slashCommandParameterService.getCommandOption(FEATURE_PARAMETER, event, String.class);
|
||||
String modeName = slashCommandParameterService.getCommandOption(MODE_PARAMETER, event, String.class);
|
||||
FeatureDefinition featureDefinition = featureConfigService.getFeatureEnum(featureName);
|
||||
FeatureMode featureMode = featureModeService.getFeatureModeForKey(featureName, modeName);
|
||||
AServer server = serverManagementService.loadServer(event.getGuild().getIdLong());
|
||||
featureModeService.enableFeatureModeForFeature(featureDefinition, server, featureMode);
|
||||
return interactionService.replyEmbed(ENABLE_MODE_RESPONSE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("feature").type(String.class).templated(true).build();
|
||||
Parameter mode = Parameter.builder().name("mode").type(String.class).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(FEATURE_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true).build();
|
||||
Parameter mode = Parameter
|
||||
.builder().name(MODE_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(featureName, mode);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName(ENABLE_MODE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("enableMode")
|
||||
.name(ENABLE_MODE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.management.FeatureManagementService;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeature;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.FeatureModeDisplay;
|
||||
@@ -17,8 +20,10 @@ import dev.sheldan.abstracto.core.models.template.commands.FeatureModesModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -30,6 +35,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class FeatureModes extends AbstractConditionableCommand {
|
||||
|
||||
public static final String FEATURE_MODES_RESPONSE_TEMPLATE_KEY = "feature_modes_response";
|
||||
private static final String FEATURE_PARAMETER = "feature";
|
||||
private static final String FEATURE_MODES_COMMAND = "featureModes";
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@@ -45,6 +52,12 @@ public class FeatureModes extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<FeatureModeDisplay> featureModes;
|
||||
@@ -62,17 +75,55 @@ public class FeatureModes extends AbstractConditionableCommand {
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
List<FeatureModeDisplay> featureModes;
|
||||
AServer server = serverManagementService.loadServer(event.getGuild());
|
||||
if(!slashCommandParameterService.hasCommandOption(FEATURE_PARAMETER, event)) {
|
||||
featureModes = featureModeService.getEffectiveFeatureModes(server);
|
||||
} else {
|
||||
String featureName = slashCommandParameterService.getCommandOption(FEATURE_PARAMETER, event, String.class);
|
||||
FeatureDefinition featureDefinition = featureConfigService.getFeatureEnum(featureName);
|
||||
AFeature feature = featureManagementService.getFeature(featureDefinition.getKey());
|
||||
featureModes = featureModeService.getEffectiveFeatureModes(server, feature);
|
||||
}
|
||||
FeatureModesModel model = FeatureModesModel
|
||||
.builder()
|
||||
.featureModes(featureModes)
|
||||
.build();
|
||||
return interactionService.replyEmbed(FEATURE_MODES_RESPONSE_TEMPLATE_KEY, model, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("feature").type(String.class).optional(true).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(FEATURE_PARAMETER)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(featureName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName(FEATURE_MODES_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("featureModes")
|
||||
.name(FEATURE_MODES_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.async(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.converter.FeatureFlagConverter;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.property.FeatureFlagProperty;
|
||||
@@ -21,6 +23,7 @@ import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -32,6 +35,7 @@ import java.util.stream.Collectors;
|
||||
@Component
|
||||
public class Features extends AbstractConditionableCommand {
|
||||
|
||||
private static final String FEATURES_COMMAND = "features";
|
||||
@Autowired
|
||||
private FeatureFlagManagementService featureFlagManagementService;
|
||||
|
||||
@@ -50,14 +54,28 @@ public class Features extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
MessageToSend messageToSend = getMessageToSend(commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
MessageToSend messageToSend = getMessageToSend(event.getGuild().getIdLong());
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private MessageToSend getMessageToSend(Long serverId) {
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
List<AFeatureFlag> features = featureFlagManagementService.getFeatureFlagsOfServer(server);
|
||||
List<FeatureFlagProperty> defaultFeatureFlagProperties = defaultFeatureFlagManagementService.getAllDefaultFeatureFlags();
|
||||
FeaturesModel featuresModel = (FeaturesModel) ContextConverter.fromCommandContext(commandContext, FeaturesModel.class);
|
||||
features.sort(Comparator.comparing(o -> o.getFeature().getKey()));
|
||||
featuresModel.setFeatures(featureFlagConverter.fromFeatureFlags(features));
|
||||
defaultFeatureFlagProperties = defaultFeatureFlagProperties
|
||||
.stream()
|
||||
.filter(featureFlagProperty ->
|
||||
@@ -68,20 +86,34 @@ public class Features extends AbstractConditionableCommand {
|
||||
.equals(featureFlagProperty.getFeatureName())))
|
||||
.collect(Collectors.toList());
|
||||
defaultFeatureFlagProperties.sort(Comparator.comparing(FeatureFlagProperty::getFeatureName));
|
||||
featuresModel.setDefaultFeatures(featureFlagConverter.fromFeatureFlagProperties(defaultFeatureFlagProperties));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("features_response", featuresModel, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
FeaturesModel featuresModel = FeaturesModel
|
||||
.builder()
|
||||
.features(featureFlagConverter.fromFeatureFlags(features))
|
||||
.defaultFeatures(featureFlagConverter.fromFeatureFlagProperties(defaultFeatureFlagProperties))
|
||||
.build();
|
||||
return templateService.renderEmbedTemplate("features_response", featuresModel, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.FEATURE)
|
||||
.commandName("list")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("features")
|
||||
.name(FEATURES_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,57 +1,112 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.service.RoleImmunityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class MakeAffected extends AbstractConditionableCommand {
|
||||
|
||||
private static final String EFFECT_PARAMETER = "effect";
|
||||
private static final String ROLE_PARAMETER = "role";
|
||||
private static final String MAKE_AFFECTED_RESPONSE = "makeAffected_response";
|
||||
private static final String MAKE_AFFECTED_COMMAND_NAME = "makeAffected";
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String name = (String) commandContext.getParameters().getParameters().get(0);
|
||||
ARole role = (ARole) commandContext.getParameters().getParameters().get(1);
|
||||
ARole actualRole = roleManagementService.findRole(role.getId());
|
||||
if(!actualRole.getServer().getId().equals(commandContext.getGuild().getIdLong())) {
|
||||
Role role = (Role) commandContext.getParameters().getParameters().get(1);
|
||||
if(!role.getGuild().getId().equals(commandContext.getGuild().getId())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
roleImmunityService.makeRoleAffected(actualRole, name);
|
||||
ARole aRole = roleManagementService.findRole(role.getIdLong());
|
||||
roleImmunityService.makeRoleAffected(aRole, name);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String name = slashCommandParameterService.getCommandOption(EFFECT_PARAMETER, event, String.class);
|
||||
Role role = slashCommandParameterService.getCommandOption(ROLE_PARAMETER, event, Role.class);
|
||||
if(!role.getGuild().getId().equals(event.getGuild().getId())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
ARole aRole = roleManagementService.findRole(role.getIdLong());
|
||||
roleImmunityService.makeRoleAffected(aRole, name);
|
||||
return interactionService.replyEmbed(MAKE_AFFECTED_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("effect").type(String.class).templated(true).build();
|
||||
Parameter role = Parameter.builder().name("role").type(ARole.class).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(EFFECT_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter role = Parameter
|
||||
.builder()
|
||||
.name(ROLE_PARAMETER)
|
||||
.type(Role.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(featureName, role);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName(MAKE_AFFECTED_COMMAND_NAME)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("makeAffected")
|
||||
.name(MAKE_AFFECTED_COMMAND_NAME)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
|
||||
@@ -1,29 +1,46 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.RoleImmunityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class MakeImmune extends AbstractConditionableCommand {
|
||||
|
||||
private static final String ROLE_PARAMETER = "role";
|
||||
private static final String EFFECT_PARAMETER = "effect";
|
||||
private static final String MAKE_IMMUNE_COMMAND = "makeImmune";
|
||||
private static final String MAKE_IMMUNE_RESPONSE = "makeImmune_response";
|
||||
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String name = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -35,18 +52,54 @@ public class MakeImmune extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String name = slashCommandParameterService.getCommandOption(EFFECT_PARAMETER, event, String.class);
|
||||
Role role = slashCommandParameterService.getCommandOption(ROLE_PARAMETER, event, Role.class);
|
||||
|
||||
if(!role.getGuild().equals(event.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
roleImmunityService.makeRoleImmune(role, name);
|
||||
return interactionService.replyEmbed(MAKE_IMMUNE_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter featureName = Parameter.builder().name("effect").type(String.class).templated(true).build();
|
||||
Parameter role = Parameter.builder().name("role").type(Role.class).templated(true).build();
|
||||
Parameter featureName = Parameter
|
||||
.builder()
|
||||
.name(EFFECT_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter role = Parameter
|
||||
.builder()
|
||||
.name(ROLE_PARAMETER)
|
||||
.type(Role.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(featureName, role);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName(MAKE_IMMUNE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("makeImmune")
|
||||
.name(MAKE_IMMUNE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.features;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.EffectType;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ShowEffectsModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.EffectTypeManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -23,33 +27,62 @@ import java.util.stream.Collectors;
|
||||
@Component
|
||||
public class ShowEffects extends AbstractConditionableCommand {
|
||||
|
||||
private static final String SHOW_EFFECTS_COMMAND = "showEffects";
|
||||
private static final String SHOW_EFFECTS_RESPONSE_TEMPLATE = "showEffects_response";
|
||||
|
||||
@Autowired
|
||||
private EffectTypeManagementService effectTypeManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<EffectType> allEffects = effectTypeManagementService.getAllEffects();
|
||||
List<String> effectKeys = allEffects.stream().map(EffectType::getEffectTypeKey).collect(Collectors.toList());
|
||||
ShowEffectsModel model = ShowEffectsModel
|
||||
.builder()
|
||||
.effects(effectKeys)
|
||||
.build();
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList("showEffects_response",
|
||||
ShowEffectsModel model = getModel();
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(SHOW_EFFECTS_RESPONSE_TEMPLATE,
|
||||
model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
ShowEffectsModel model = getModel();
|
||||
return interactionService.replyEmbed(SHOW_EFFECTS_RESPONSE_TEMPLATE, model, event)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private ShowEffectsModel getModel() {
|
||||
List<EffectType> allEffects = effectTypeManagementService.getAllEffects();
|
||||
List<String> effectKeys = allEffects.stream().map(EffectType::getEffectTypeKey).collect(Collectors.toList());
|
||||
return ShowEffectsModel
|
||||
.builder()
|
||||
.effects(effectKeys)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName(SHOW_EFFECTS_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("showEffects")
|
||||
.name(SHOW_EFFECTS_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -1,27 +1,46 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.profanity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class AddProfanityRegex extends AbstractConditionableCommand {
|
||||
|
||||
private static final String PROFANITY_GROUP_PARAMETER = "profanityGroup";
|
||||
private static final String PROFANITY_NAME_PARAMETER = "profanityName";
|
||||
private static final String REGEX_PARAMETER = "regex";
|
||||
private static final String REPLACEMENT_PARAMETER = "replacement";
|
||||
private static final String ADD_PROFANITY_REGEX_RESPONSE = "addProfanityRegex_response";
|
||||
private static final String ADD_PROFANITY_REGEX_COMMAND = "addProfanityRegex";
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -38,19 +57,68 @@ public class AddProfanityRegex extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String profanityGroup = slashCommandParameterService.getCommandOption(PROFANITY_GROUP_PARAMETER, event, String.class);
|
||||
String profanityName = slashCommandParameterService.getCommandOption(PROFANITY_NAME_PARAMETER, event, String.class);
|
||||
String regex = slashCommandParameterService.getCommandOption(REGEX_PARAMETER, event, String.class);
|
||||
Long serverId = event.getGuild().getIdLong();
|
||||
if(slashCommandParameterService.hasCommandOption(REPLACEMENT_PARAMETER, event)) {
|
||||
String replacement = slashCommandParameterService.getCommandOption(REPLACEMENT_PARAMETER, event, String.class);
|
||||
profanityService.createProfanityRegex(serverId, profanityGroup, profanityName, regex, replacement);
|
||||
} else {
|
||||
profanityService.createProfanityRegex(serverId, profanityGroup, profanityName, regex);
|
||||
}
|
||||
return interactionService.replyEmbed(ADD_PROFANITY_REGEX_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter profanityGroupParameter = Parameter.builder().name("profanityGroup").type(String.class).templated(true).build();
|
||||
Parameter nameParameter = Parameter.builder().name("profanityName").type(String.class).templated(true).build();
|
||||
Parameter regexParameter = Parameter.builder().name("regex").type(String.class).templated(true).build();
|
||||
Parameter replacement = Parameter.builder().name("replacement").type(String.class).optional(true).templated(true).build();
|
||||
Parameter profanityGroupParameter = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_GROUP_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter nameParameter = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter regexParameter = Parameter
|
||||
.builder()
|
||||
.name(REGEX_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter replacement = Parameter
|
||||
.builder()
|
||||
.name(REPLACEMENT_PARAMETER)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(profanityGroupParameter, nameParameter, regexParameter, replacement);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.PROFANITY)
|
||||
.commandName(ADD_PROFANITY_REGEX_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("addProfanityRegex")
|
||||
.name(ADD_PROFANITY_REGEX_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.profanity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class CreateProfanityGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String PROFANITY_GROUP_NAME_PARAMETER = "profanityGroupName";
|
||||
private static final String CREATE_PROFANITY_GROUP_RESPONSE = "createProfanityGroup_response";
|
||||
private static final String CREATE_PROFANITY_GROUP_COMMAND = "createProfanityGroup";
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String profanityGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -29,16 +45,40 @@ public class CreateProfanityGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String profanityGroup = slashCommandParameterService.getCommandOption(PROFANITY_GROUP_NAME_PARAMETER, event, String.class);
|
||||
profanityService.createProfanityGroup(event.getGuild().getIdLong(), profanityGroup);
|
||||
return interactionService.replyEmbed(CREATE_PROFANITY_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter profanityGroupName = Parameter.builder().name("profanityGroupName").type(String.class).templated(true).build();
|
||||
Parameter profanityGroupName = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_GROUP_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(profanityGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.PROFANITY)
|
||||
.commandName(CREATE_PROFANITY_GROUP_COMMAND)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("createProfanityGroup")
|
||||
.name(CREATE_PROFANITY_GROUP_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,27 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.profanity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class DeleteProfanityGroup extends AbstractConditionableCommand {
|
||||
|
||||
private static final String PROFANITY_GROUP_NAME_PARAMETER = "profanityGroupName";
|
||||
private static final String DELETE_PROFANITY_GROUP_COMMAND = "deleteProfanityGroup";
|
||||
private static final String DELETE_PROFANITY_GROUP_RESPONSE = "deleteProfanityGroup_response";
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String profanityGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -29,15 +45,40 @@ public class DeleteProfanityGroup extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String profanityGroup = slashCommandParameterService.getCommandOption(PROFANITY_GROUP_NAME_PARAMETER, event, String.class);
|
||||
profanityService.deleteProfanityGroup(event.getGuild().getIdLong(), profanityGroup);
|
||||
return interactionService.replyEmbed(DELETE_PROFANITY_GROUP_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter profanityGroupParameter = Parameter.builder().name("profanityGroupName").type(String.class).templated(true).build();
|
||||
Parameter profanityGroupParameter = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_GROUP_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(profanityGroupParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.PROFANITY)
|
||||
.commandName(DELETE_PROFANITY_GROUP_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("deleteProfanityGroup")
|
||||
.name(DELETE_PROFANITY_GROUP_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,27 +1,44 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.profanity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class RemoveProfanityRegex extends AbstractConditionableCommand {
|
||||
|
||||
private static final String REMOVE_PROFANITY_REGEX_COMMAND = "removeProfanityRegex";
|
||||
private static final String PROFANITY_NAME_PARAMETER = "profanityName";
|
||||
private static final String PROFANITY_GROUP_NAME_PARAMETER = "profanityGroupName";
|
||||
private static final String REMOVE_PROFANITY_REGEX_RESPONSE = "removeProfanityRegex_response";
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -31,17 +48,47 @@ public class RemoveProfanityRegex extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String profanityGroup = slashCommandParameterService.getCommandOption(PROFANITY_GROUP_NAME_PARAMETER, event, String.class);
|
||||
profanityService.deleteProfanityGroup(event.getGuild().getIdLong(), profanityGroup);
|
||||
return interactionService.replyEmbed(REMOVE_PROFANITY_REGEX_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter profanityGroupParameter = Parameter.builder().name("profanityGroupName").type(String.class).templated(true).build();
|
||||
Parameter profanityNameParameter = Parameter.builder().name("profanityName").type(String.class).templated(true).build();
|
||||
Parameter profanityGroupParameter = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_GROUP_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter profanityNameParameter = Parameter
|
||||
.builder()
|
||||
.name(PROFANITY_NAME_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(profanityGroupParameter, profanityNameParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.PROFANITY)
|
||||
.commandName(REMOVE_PROFANITY_REGEX_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("removeProfanityRegex")
|
||||
.name(REMOVE_PROFANITY_REGEX_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.profanity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityGroup;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ProfanityConfigModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
@@ -16,6 +18,7 @@ import dev.sheldan.abstracto.core.service.management.ProfanityGroupManagementSer
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -26,6 +29,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class ShowProfanityConfig extends AbstractConditionableCommand {
|
||||
|
||||
public static final String SHOW_PROFANITY_CONFIG_RESPONSE_TEMPLATE_KEY = "showProfanityConfig_response";
|
||||
public static final String SHOW_PROFANITY_CONFIG_COMMAND = "showProfanityConfig";
|
||||
@Autowired
|
||||
private ProfanityGroupManagementService profanityGroupManagementService;
|
||||
|
||||
@@ -35,25 +39,55 @@ public class ShowProfanityConfig extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
ProfanityConfigModel model = (ProfanityConfigModel) ContextConverter.slimFromCommandContext(commandContext, ProfanityConfigModel.class);
|
||||
Long serverId = commandContext.getGuild().getIdLong();
|
||||
List<ProfanityGroup> groups = profanityGroupManagementService.getAllForServer(serverId);
|
||||
model.setProfanityGroups(groups);
|
||||
MessageToSend message = templateService.renderEmbedTemplate(SHOW_PROFANITY_CONFIG_RESPONSE_TEMPLATE_KEY, model, serverId);
|
||||
MessageToSend message = getMessageToSend(serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(message, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long serverId = event.getGuild().getIdLong();
|
||||
MessageToSend message = getMessageToSend(serverId);
|
||||
return interactionService.replyMessageToSend(message, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private MessageToSend getMessageToSend(Long serverId) {
|
||||
List<ProfanityGroup> groups = profanityGroupManagementService.getAllForServer(serverId);
|
||||
ProfanityConfigModel model = ProfanityConfigModel
|
||||
.builder()
|
||||
.profanityGroups(groups)
|
||||
.build();
|
||||
return templateService.renderEmbedTemplate(SHOW_PROFANITY_CONFIG_RESPONSE_TEMPLATE_KEY, model, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.PROFANITY)
|
||||
.commandName(SHOW_PROFANITY_CONFIG_COMMAND)
|
||||
.build();
|
||||
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("showProfanityConfig")
|
||||
.name(SHOW_PROFANITY_CONFIG_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,78 +1,165 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.exception.CustomTemplateNotFoundException;
|
||||
import dev.sheldan.abstracto.core.exception.UploadFileTooLargeException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.GetCustomTemplateModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.model.database.CustomTemplate;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.templating.service.management.CustomTemplateManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FileService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GetCustomTemplate extends AbstractConditionableCommand {
|
||||
|
||||
private static final String GET_CUSTOM_TEMPLATE_COMMAND = "getCustomTemplate";
|
||||
private static final String TEMPLATE_KEY_PARAMETER = "templateKey";
|
||||
private static final String GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY = "getCustomTemplate_response";
|
||||
|
||||
@Autowired
|
||||
private CustomTemplateManagementService customTemplateManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
private static final String GET_CUSTOM_TEMPLATE_FILE_NAME_TEMPLATE_KEY = "getCustomTemplate_file_name";
|
||||
private static final String GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY = "getCustomTemplate_response";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
String templateKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
Optional<CustomTemplate> templateOptional = customTemplateManagementService.getCustomTemplate(templateKey, commandContext.getGuild().getIdLong());
|
||||
if(templateOptional.isPresent()) {
|
||||
CustomTemplate template = templateOptional.get();
|
||||
GetCustomTemplateModel model = (GetCustomTemplateModel) ContextConverter.slimFromCommandContext(commandContext, GetCustomTemplateModel.class);
|
||||
model.setCreated(template.getCreated());
|
||||
model.setLastModified(template.getLastModified());
|
||||
model.setTemplateContent(template.getContent());
|
||||
model.setTemplateKey(templateKey);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendFileToChannel(template.getContent(),
|
||||
GET_CUSTOM_TEMPLATE_FILE_NAME_TEMPLATE_KEY, GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
GetCustomTemplateModel model = getModel(templateKey, commandContext.getGuild());
|
||||
File tempFile = fileService.createTempFile(templateKey + ".ftl");
|
||||
try {
|
||||
fileService.writeContentToFile(tempFile, model.getTemplateContent());
|
||||
long maxFileSize = commandContext.getGuild().getIdLong();
|
||||
// in this case, we cannot upload the file, so we need to fail
|
||||
if(tempFile.length() > maxFileSize) {
|
||||
throw new UploadFileTooLargeException(tempFile.length(), maxFileSize);
|
||||
}
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, commandContext.getGuild().getIdLong());
|
||||
messageToSend.getAttachedFiles().get(0).setFile(tempFile);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannelList(GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
} catch (IOException e) {
|
||||
throw new AbstractoRunTimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
fileService.safeDelete(tempFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete temporary get custom template file {}.", tempFile.getAbsoluteFile(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private GetCustomTemplateModel getModel(String templateKey, Guild guild) {
|
||||
Optional<CustomTemplate> templateOptional = customTemplateManagementService.getCustomTemplate(templateKey, guild.getIdLong());
|
||||
return templateOptional.map(customTemplate -> {
|
||||
CustomTemplate template = templateOptional.get();
|
||||
return GetCustomTemplateModel
|
||||
.builder()
|
||||
.created(template.getCreated())
|
||||
.lastModified(template.getLastModified())
|
||||
.templateContent(template.getContent())
|
||||
.templateKey(templateKey)
|
||||
.build();
|
||||
}).orElseThrow(() -> new CustomTemplateNotFoundException(templateKey, guild));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String templateKey = slashCommandParameterService.getCommandOption(TEMPLATE_KEY_PARAMETER, event, String.class);
|
||||
GetCustomTemplateModel model = getModel(templateKey, event.getGuild());
|
||||
File tempFile = fileService.createTempFile(templateKey + ".ftl");
|
||||
try {
|
||||
fileService.writeContentToFile(tempFile, model.getTemplateContent());
|
||||
long maxFileSize = event.getGuild().getMaxFileSize();
|
||||
// in this case, we cannot upload the file, so we need to fail
|
||||
if(tempFile.length() > maxFileSize) {
|
||||
throw new UploadFileTooLargeException(tempFile.length(), maxFileSize);
|
||||
}
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GET_CUSTOM_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, event.getGuild().getIdLong());
|
||||
messageToSend.getAttachedFiles().get(0).setFile(tempFile);
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
} catch (IOException e) {
|
||||
throw new AbstractoRunTimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
fileService.safeDelete(tempFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete temporary get custom template file {}.", tempFile.getAbsoluteFile(), e);
|
||||
}
|
||||
}
|
||||
throw new CustomTemplateNotFoundException(templateKey, commandContext.getGuild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter templateKeyParameter = Parameter.builder().name("templateKey").type(String.class).templated(true).build();
|
||||
Parameter templateKeyParameter = Parameter
|
||||
.builder()
|
||||
.name(TEMPLATE_KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(templateKeyParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INTERNAL)
|
||||
.commandName(GET_CUSTOM_TEMPLATE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("getCustomTemplate")
|
||||
.name(GET_CUSTOM_TEMPLATE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,78 +1,145 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.exception.TemplateNotFoundException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.GetTemplateModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.templating.model.database.Template;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.templating.service.management.TemplateManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FileService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GetTemplate extends AbstractConditionableCommand {
|
||||
|
||||
private static final String GET_TEMPLATE_COMMAND = "getTemplate";
|
||||
private static final String TEMPLATE_KEY_PARAMETER = "templateKey";
|
||||
private static final String GET_TEMPLATE_RESPONSE_TEMPLATE_KEY = "getTemplate_response";
|
||||
|
||||
@Autowired
|
||||
private TemplateManagementService templateManagementService;
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
private static final String GET_TEMPLATE_FILE_NAME_TEMPLATE_KEY = "getTemplate_file_name";
|
||||
private static final String GET_TEMPLATE_RESPONSE_TEMPLATE_KEY = "getTemplate_response";
|
||||
private FileService fileService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
String templateKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
Optional<Template> templateOptional = templateManagementService.getTemplateByKey(templateKey);
|
||||
if(templateOptional.isPresent()) {
|
||||
Template template = templateOptional.get();
|
||||
GetTemplateModel model = (GetTemplateModel) ContextConverter.slimFromCommandContext(commandContext, GetTemplateModel.class);
|
||||
model.setCreated(template.getCreated());
|
||||
model.setLastModified(template.getLastModified());
|
||||
model.setTemplateContent(template.getContent());
|
||||
model.setTemplateKey(templateKey);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendFileToChannel(template.getContent(),
|
||||
GET_TEMPLATE_FILE_NAME_TEMPLATE_KEY, GET_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
GetTemplateModel model = getModel(templateKey);
|
||||
File tempFile = fileService.createTempFile(templateKey + ".ftl");
|
||||
try {
|
||||
fileService.writeContentToFile(tempFile, model.getTemplateContent());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GET_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, commandContext.getGuild().getIdLong());
|
||||
messageToSend.getAttachedFiles().get(0).setFile(tempFile);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
} catch (IOException e) {
|
||||
throw new AbstractoRunTimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
fileService.safeDelete(tempFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete temporary get template file {}.", tempFile.getAbsoluteFile(), e);
|
||||
}
|
||||
}
|
||||
throw new TemplateNotFoundException(templateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String templateKey = slashCommandParameterService.getCommandOption(TEMPLATE_KEY_PARAMETER, event, String.class);
|
||||
GetTemplateModel model = getModel(templateKey);
|
||||
File tempFile = fileService.createTempFile(templateKey + ".ftl");
|
||||
try {
|
||||
fileService.writeContentToFile(tempFile, model.getTemplateContent());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GET_TEMPLATE_RESPONSE_TEMPLATE_KEY, model, event.getGuild().getIdLong());
|
||||
messageToSend.getAttachedFiles().get(0).setFile(tempFile);
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
} catch (IOException e) {
|
||||
throw new AbstractoRunTimeException(e);
|
||||
} finally {
|
||||
try {
|
||||
fileService.safeDelete(tempFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete temporary get template file {}.", tempFile.getAbsoluteFile(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GetTemplateModel getModel(String templateKey) {
|
||||
return templateManagementService.getTemplateByKey(templateKey)
|
||||
.map(template -> GetTemplateModel
|
||||
.builder()
|
||||
.created(template.getCreated())
|
||||
.lastModified(template.getLastModified())
|
||||
.templateContent(template.getContent())
|
||||
.templateKey(templateKey)
|
||||
.build()).orElseThrow(() -> new TemplateNotFoundException(templateKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
Parameter templateKeyParameter = Parameter.builder().name("templateKey").type(String.class).templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter templateKeyParameter = Parameter
|
||||
.builder()
|
||||
.name(TEMPLATE_KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(templateKeyParameter);
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INTERNAL)
|
||||
.commandName(GET_TEMPLATE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("getTemplate")
|
||||
.name(GET_TEMPLATE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.supportsEmbedException(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,34 +1,50 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.CustomTemplateNotFoundException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.model.database.CustomTemplate;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.templating.service.management.CustomTemplateManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class ResetTemplate extends AbstractConditionableCommand {
|
||||
|
||||
private static final String RESET_TEMPLATE_COMMAND = "resetTemplate";
|
||||
private static final String TEMPLATE_KEY_PARAMETER = "templateKey";
|
||||
private static final String RESET_TEMPLATE_RESPONSE_TEMPLATE_KEY = "resetTemplate_response";
|
||||
|
||||
@Autowired
|
||||
private CustomTemplateManagementService customTemplateManagementService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String templateKey = (String) commandContext.getParameters().getParameters().get(0);
|
||||
@@ -41,16 +57,47 @@ public class ResetTemplate extends AbstractConditionableCommand {
|
||||
throw new CustomTemplateNotFoundException(templateKey, commandContext.getGuild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String templateKey = slashCommandParameterService.getCommandOption(TEMPLATE_KEY_PARAMETER, event, String.class);
|
||||
Optional<CustomTemplate> templateOptional = customTemplateManagementService.getCustomTemplate(templateKey, event.getGuild().getIdLong());
|
||||
if (templateOptional.isPresent()) {
|
||||
customTemplateManagementService.deleteCustomTemplate(templateOptional.get());
|
||||
templateService.clearCache();
|
||||
return interactionService.replyEmbed(RESET_TEMPLATE_RESPONSE_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
throw new CustomTemplateNotFoundException(templateKey, event.getGuild());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
Parameter templateKeyParameter = Parameter.builder().name("templateKey").type(String.class).templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter templateKeyParameter = Parameter
|
||||
.builder()
|
||||
.name(TEMPLATE_KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(templateKeyParameter);
|
||||
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INTERNAL)
|
||||
.commandName(RESET_TEMPLATE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("resetTemplate")
|
||||
.name(RESET_TEMPLATE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.exception.AbstractoTemplatedException;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.templating.service.management.CustomTemplateManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -23,11 +29,17 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SetTemplate extends AbstractConditionableCommand {
|
||||
|
||||
private static final String TEMPLATE_KEY_PARAMETER = "templateKey";
|
||||
private static final String FILE_PARAMETER = "file";
|
||||
private static final String SET_TEMPLATE_COMMAND = "setTemplate";
|
||||
private static final String SET_TEMPLATE_RESPONSE_TEMPLATE = "setTemplate_response";
|
||||
|
||||
@Autowired
|
||||
private CustomTemplateManagementService customTemplateManagementService;
|
||||
|
||||
@@ -37,6 +49,12 @@ public class SetTemplate extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameter = commandContext.getParameters().getParameters();
|
||||
@@ -59,6 +77,37 @@ public class SetTemplate extends AbstractConditionableCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String templateKey = slashCommandParameterService.getCommandOption(TEMPLATE_KEY_PARAMETER, event, String.class);
|
||||
Message.Attachment templateAttachment = slashCommandParameterService.getCommandOption(FILE_PARAMETER, event, File.class, Message.Attachment.class);
|
||||
File templateFile = fileService.createTempFile(Math.random() + "");
|
||||
return templateAttachment.downloadToFile(templateFile).thenCompose(file -> {
|
||||
try {
|
||||
return updateTemplate(event, templateFile, templateKey);
|
||||
} catch (IOException e) {
|
||||
log.error("IO Exception when loading input file.", e);
|
||||
throw new AbstractoTemplatedException("Failed to set template.", "failed_to_set_template_exception", e);
|
||||
} finally {
|
||||
try {
|
||||
if(templateFile != null) {
|
||||
fileService.safeDelete(templateFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to delete downloaded template file.", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private CompletableFuture<CommandResult> updateTemplate(SlashCommandInteractionEvent event, File templateFile, String templateKey) throws IOException {
|
||||
String templateContent = FileUtils.readFileToString(templateFile, StandardCharsets.UTF_8);
|
||||
customTemplateManagementService.createOrUpdateCustomTemplate(templateKey, templateContent, event.getGuild().getIdLong());
|
||||
templateService.clearCache();
|
||||
return interactionService.replyEmbed(SET_TEMPLATE_RESPONSE_TEMPLATE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
@@ -66,15 +115,37 @@ public class SetTemplate extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter templateKeyParameter = Parameter.builder().name("templateKey").type(String.class).templated(true).build();
|
||||
Parameter fileAttachmentParameter = Parameter.builder().name("file").type(File.class).templated(true).build();
|
||||
Parameter templateKeyParameter = Parameter
|
||||
.builder()
|
||||
.name(TEMPLATE_KEY_PARAMETER)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter fileAttachmentParameter = Parameter
|
||||
.builder()
|
||||
.name(FILE_PARAMETER)
|
||||
.type(File.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(templateKeyParameter, fileAttachmentParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INTERNAL)
|
||||
.commandName(SET_TEMPLATE_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("setTemplate")
|
||||
.name(SET_TEMPLATE_COMMAND)
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package dev.sheldan.abstracto.core.commands.help;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -16,11 +20,14 @@ import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class Documentation implements Command {
|
||||
public class Documentation extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final String DOCUMENTATION_RESPONSE_TEMPLATE_KEY = "documentation_response";
|
||||
|
||||
@Override
|
||||
@@ -29,15 +36,33 @@ public class Documentation implements Command {
|
||||
.thenApply(unused -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
return interactionService.replyEmbed(DOCUMENTATION_RESPONSE_TEMPLATE_KEY, new Object(), event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.INFO)
|
||||
.commandName("documentation")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("documentation")
|
||||
.async(true)
|
||||
.aliases(Arrays.asList("docu", "docs"))
|
||||
.module(SupportModuleDefinition.SUPPORT)
|
||||
.help(helpInfo)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package dev.sheldan.abstracto.core.commands.help;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionResult;
|
||||
import dev.sheldan.abstracto.core.command.config.*;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.service.*;
|
||||
@@ -38,7 +38,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class Help implements Command {
|
||||
public class Help extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ModuleRegistry moduleService;
|
||||
@@ -136,9 +136,11 @@ public class Help implements Command {
|
||||
}));
|
||||
module.setCommands(filteredCommand);
|
||||
List<ModuleDefinition> subModules = moduleService.getSubModules(moduleDefinition);
|
||||
HelpModuleDetailsModel model = (HelpModuleDetailsModel) ContextConverter.fromCommandContext(commandContext, HelpModuleDetailsModel.class);
|
||||
model.setModule(module);
|
||||
model.setSubModules(subModules);
|
||||
HelpModuleDetailsModel model = HelpModuleDetailsModel
|
||||
.builder()
|
||||
.subModules(subModules)
|
||||
.module(module)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_module_details_response", model, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
@@ -157,10 +159,14 @@ public class Help implements Command {
|
||||
ACommand aCommand = commandManagementService.findCommandByName(command.getConfiguration().getName());
|
||||
List<String> aliases = commandInServerAliasService.getAliasesForCommand(commandContext.getGuild().getIdLong(), command.getConfiguration().getName());
|
||||
ACommandInAServer aCommandInAServer = commandInServerManagementService.getCommandForServer(aCommand, commandContext.getGuild().getIdLong());
|
||||
HelpCommandDetailsModel model = (HelpCommandDetailsModel) ContextConverter.fromCommandContext(commandContext, HelpCommandDetailsModel.class);
|
||||
model.setServerSpecificAliases(aliases);
|
||||
CommandCoolDownConfig coolDownConfig = getCoolDownConfig(command, contextIds);
|
||||
model.setCooldowns(coolDownConfig);
|
||||
HelpCommandDetailsModel model = HelpCommandDetailsModel
|
||||
.builder()
|
||||
.serverSpecificAliases(aliases)
|
||||
.cooldowns(coolDownConfig)
|
||||
.usage(commandService.generateUsage(command))
|
||||
.command(command.getConfiguration())
|
||||
.build();
|
||||
if(Boolean.TRUE.equals(aCommandInAServer.getRestricted())) {
|
||||
model.setAllowedRoles(roleService.getRolesFromGuild(aCommandInAServer.getAllowedRoles()));
|
||||
model.setRestricted(true);
|
||||
@@ -174,8 +180,6 @@ public class Help implements Command {
|
||||
if(!effects.isEmpty()) {
|
||||
model.setEffects(effects);
|
||||
}
|
||||
model.setUsage(commandService.generateUsage(command));
|
||||
model.setCommand(command.getConfiguration());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_command_details_response", model, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
@@ -209,8 +213,10 @@ public class Help implements Command {
|
||||
log.debug("Displaying help overview response.");
|
||||
ModuleDefinition moduleDefinition = moduleService.getDefaultModule();
|
||||
List<ModuleDefinition> subModules = moduleService.getSubModules(moduleDefinition);
|
||||
HelpModuleOverviewModel model = (HelpModuleOverviewModel) ContextConverter.fromCommandContext(commandContext, HelpModuleOverviewModel.class);
|
||||
model.setModules(subModules);
|
||||
HelpModuleOverviewModel model = HelpModuleOverviewModel
|
||||
.builder()
|
||||
.modules(subModules)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_module_overview_response", model, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
|
||||
@@ -5,23 +5,28 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.EchoModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
public class Echo extends AbstractConditionableCommand {
|
||||
|
||||
private static final String TEMPLATE_NAME = "echo_response";
|
||||
public static final String ECHO_COMMAND = "echo";
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
@@ -29,29 +34,57 @@ public class Echo extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
commandContext.getParameters().getParameters().forEach(o ->
|
||||
sb.append(o.toString())
|
||||
);
|
||||
EchoModel model = EchoModel.builder().text(sb.toString()).build();
|
||||
EchoModel model = EchoModel
|
||||
.builder()
|
||||
.text(sb.toString())
|
||||
.build();
|
||||
String textToSend = templateService.renderTemplate(TEMPLATE_NAME, model, commandContext.getGuild().getIdLong());
|
||||
channelService.sendTextToChannel(textToSend, commandContext.getChannel());
|
||||
return CommandResult.fromIgnored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
EchoModel model = EchoModel
|
||||
.builder()
|
||||
.text(event.getOption("input").getAsString())
|
||||
.build();
|
||||
return interactionService.replyMessage(TEMPLATE_NAME, model, event)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("input").type(String.class).templated(true).remainder(true).build());
|
||||
parameters.add(Parameter
|
||||
.builder()
|
||||
.name("input")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.remainder(true)
|
||||
.build());
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(ECHO_COMMAND)
|
||||
.build();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("echo")
|
||||
.name(ECHO_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
|
||||
@@ -1,49 +1,74 @@
|
||||
package dev.sheldan.abstracto.core.commands.utility;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.PingModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
public class Ping implements Command {
|
||||
public class Ping extends AbstractConditionableCommand {
|
||||
|
||||
public static final String PING_TEMPLATE = "ping_response";
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
private static final String PING_COMMAND = "ping";
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
long ping = commandContext.getJda().getGatewayPing();
|
||||
PingModel model = PingModel.builder().latency(ping).build();
|
||||
PingModel model = buildModel(commandContext.getJda());
|
||||
return channelService.sendTextTemplateInTextChannel(PING_TEMPLATE, model, commandContext.getChannel())
|
||||
.thenApply(message -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
PingModel model = buildModel(event.getJDA());
|
||||
return interactionService.replyMessage(PING_TEMPLATE, model, event)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private PingModel buildModel(JDA jda) {
|
||||
long ping = jda.getGatewayPing();
|
||||
return PingModel
|
||||
.builder()
|
||||
.latency(ping)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(PING_COMMAND)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("ping")
|
||||
.name(PING_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.help(helpInfo)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -1,33 +1,41 @@
|
||||
package dev.sheldan.abstracto.core.commands.utility;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.CoreSlashCommandNames;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
|
||||
import dev.sheldan.abstracto.core.command.config.*;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class SetEmote extends AbstractConditionableCommand {
|
||||
|
||||
private static final String EMOTE_KEY_PARAMETER = "emoteKey";
|
||||
private static final String EMOTE_PARAMETER = "emote";
|
||||
private static final String RESPONSE_TEMPLATE = "setEmote_response";
|
||||
|
||||
@Autowired
|
||||
private EmoteManagementService emoteManagementService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
@@ -38,19 +46,50 @@ public class SetEmote extends AbstractConditionableCommand {
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String emoteKey = slashCommandParameterService.getCommandOption(EMOTE_KEY_PARAMETER, event, String.class);
|
||||
String emote = slashCommandParameterService.getCommandOption(EMOTE_PARAMETER, event, String.class);
|
||||
AEmote aEmote = slashCommandParameterService.loadAEmoteFromString(emote, event);
|
||||
emoteManagementService.setEmoteToAEmote(emoteKey, aEmote, event.getGuild().getIdLong());
|
||||
return interactionService.replyEmbed(RESPONSE_TEMPLATE, new Object(), event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<ParameterValidator> emoteKeyValidators = Arrays.asList(MaxStringLengthValidator.max(255L));
|
||||
Parameter emoteKey = Parameter.builder().name("emoteKey").validators(emoteKeyValidators).type(String.class).templated(true).build();
|
||||
Parameter emote = Parameter.builder().name("emote").type(AEmote.class).templated(true).build();
|
||||
Parameter emoteKey = Parameter
|
||||
.builder()
|
||||
.name(EMOTE_KEY_PARAMETER)
|
||||
.validators(emoteKeyValidators)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter emote = Parameter
|
||||
.builder()
|
||||
.name(EMOTE_PARAMETER)
|
||||
.type(AEmote.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(emoteKey, emote);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CoreSlashCommandNames.CONFIG)
|
||||
.commandName("setEmote")
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("setEmote")
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
|
||||
@@ -4,15 +4,18 @@ import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.SystemInfo;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.UptimeModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -22,33 +25,60 @@ import java.util.concurrent.CompletableFuture;
|
||||
public class Uptime extends AbstractConditionableCommand {
|
||||
|
||||
public static final String UPTIME_RESPONSE_TEMPLATE_KEY = "uptime_response";
|
||||
private static final String UPTIME_COMMAND = "uptime";
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
SystemInfo systemInfo = botService.getSystemInfo();
|
||||
UptimeModel model = UptimeModel
|
||||
.builder()
|
||||
.uptime(systemInfo.getUptime())
|
||||
.startDate(systemInfo.getStartTime())
|
||||
.build();
|
||||
UptimeModel model = getModel();
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(UPTIME_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
UptimeModel model = getModel();
|
||||
return interactionService.replyEmbed(UPTIME_RESPONSE_TEMPLATE_KEY, model, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
private UptimeModel getModel() {
|
||||
SystemInfo systemInfo = botService.getSystemInfo();
|
||||
return UptimeModel
|
||||
.builder()
|
||||
.uptime(systemInfo.getUptime())
|
||||
.startDate(systemInfo.getStartTime())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(UPTIME_COMMAND)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("uptime")
|
||||
.name(UPTIME_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.help(helpInfo)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,11 @@ public class ListenerExecutorConfig {
|
||||
return executorService.setupExecutorFor("messageContextCommandListener");
|
||||
}
|
||||
|
||||
@Bean(name = "slashCommandExecutor")
|
||||
public TaskExecutor slashCommandExecutor() {
|
||||
return executorService.setupExecutorFor("slashCommandListener");
|
||||
}
|
||||
|
||||
@Bean(name = "emoteDeletedExecutor")
|
||||
public TaskExecutor emoteDeletedExecutor() {
|
||||
return executorService.setupExecutorFor("emoteDeletedListener");
|
||||
|
||||
@@ -10,7 +10,6 @@ import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.PaginatorServiceBean;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageConfiguration;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
@@ -33,17 +32,11 @@ public class PaginatorButtonListener implements ButtonClickedListener {
|
||||
@Autowired
|
||||
private TemplateServiceBean templateServiceBean;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
PaginatorButtonPayload payload = (PaginatorButtonPayload) model.getDeserializedPayload();
|
||||
|
||||
Message originalMessage = model.getEvent().getMessage();
|
||||
if(originalMessage == null) {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
}
|
||||
if(payload.getAllowedUser() != null && model.getEvent().getUser().getIdLong() != payload.getAllowedUser()) {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,6 @@ public class SyncButtonClickedListenerBean extends ListenerAdapter {
|
||||
@Qualifier("buttonClickedExecutor")
|
||||
private TaskExecutor buttonClickedExecutor;
|
||||
|
||||
@Autowired
|
||||
private ListenerService listenerService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@@ -68,6 +65,7 @@ public class SyncButtonClickedListenerBean extends ListenerAdapter {
|
||||
@Override
|
||||
public void onButtonInteraction(@NotNull ButtonInteractionEvent event) {
|
||||
if(listenerList == null) return;
|
||||
// TODO remove this and make this configurable
|
||||
event.deferEdit().queue();
|
||||
CompletableFuture.runAsync(() -> self.executeListenerLogic(event), buttonClickedExecutor).exceptionally(throwable -> {
|
||||
log.error("Failed to execute listener logic in async button event.", throwable);
|
||||
|
||||
@@ -17,6 +17,7 @@ import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementServi
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -65,7 +66,7 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannelToChannelGroup(String channelGroupName, TextChannel textChannel) {
|
||||
public void addChannelToChannelGroup(String channelGroupName, GuildChannel textChannel) {
|
||||
addChannelToChannelGroup(channelGroupName, textChannel.getIdLong(), textChannel.getGuild().getIdLong());
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.AttachedFile;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
@@ -19,6 +20,7 @@ import net.dv8tion.jda.api.interactions.components.ActionComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.ItemComponent;
|
||||
import net.dv8tion.jda.api.requests.restaction.MessageAction;
|
||||
import net.dv8tion.jda.api.utils.AttachmentOption;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -256,13 +258,28 @@ public class ChannelServiceBean implements ChannelService {
|
||||
}
|
||||
}
|
||||
|
||||
if(messageToSend.hasFileToSend()) {
|
||||
if(messageToSend.hasFilesToSend()) {
|
||||
if(!allMessageActions.isEmpty()) {
|
||||
// in case there has not been a message, we need to increment it
|
||||
allMessageActions.set(0, allMessageActions.get(0).addFile(messageToSend.getFileToSend()));
|
||||
messageToSend.getAttachedFiles().forEach(attachedFile -> {
|
||||
String fileNameToUse = attachedFile.getFileName() != null ? attachedFile.getFileName() : attachedFile.getFile().getName();
|
||||
allMessageActions.set(0, allMessageActions.get(0)
|
||||
.addFile(attachedFile.getFile(), fileNameToUse, attachedFile.getOptions().toArray(new AttachmentOption[0])));
|
||||
});
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
allMessageActions.add(textChannel.sendFile(messageToSend.getFileToSend()));
|
||||
messageToSend.getAttachedFiles().forEach(attachedFile -> allMessageActions.set(0, allMessageActions.get(0)
|
||||
.addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]))));
|
||||
|
||||
AttachedFile firstAttachment = messageToSend.getAttachedFiles().get(0);
|
||||
String fileNameToUse = firstAttachment.getFileName() != null ? firstAttachment.getFileName() : firstAttachment.getFile().getName();
|
||||
allMessageActions.add(textChannel.sendFile(firstAttachment.getFile(), fileNameToUse, firstAttachment.getOptions().toArray(new AttachmentOption[0])));
|
||||
if(messageToSend.getAttachedFiles().size() > 1) {
|
||||
messageToSend.getAttachedFiles().stream().skip(1).forEach(attachedFile -> {
|
||||
String innerFileNameToUse = attachedFile.getFileName() != null ? attachedFile.getFileName() : attachedFile.getFile().getName();
|
||||
allMessageActions.set(0, allMessageActions.get(0).addFile(attachedFile.getFile(), innerFileNameToUse, attachedFile.getOptions().toArray(new AttachmentOption[0])));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<Message.MentionType> allowedMentions = allowedMentionService.getAllowedMentionsFor(textChannel, messageToSend);
|
||||
@@ -604,7 +621,12 @@ public class ChannelServiceBean implements ChannelService {
|
||||
} else {
|
||||
messageToSend = templateService.renderEmbedTemplate(messageTemplate, model);
|
||||
}
|
||||
messageToSend.setFileToSend(tempFile);
|
||||
AttachedFile file = AttachedFile
|
||||
.builder()
|
||||
.file(tempFile)
|
||||
.fileName(fileName)
|
||||
.build();
|
||||
messageToSend.setAttachedFiles(Arrays.asList(file));
|
||||
return sendMessageToSendToChannel(messageToSend, channel);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to write local temporary file for template download.", e);
|
||||
@@ -630,9 +652,14 @@ public class ChannelServiceBean implements ChannelService {
|
||||
throw new UploadFileTooLargeException(tempFile.length(), maxFileSize);
|
||||
}
|
||||
}
|
||||
AttachedFile attachedFile = AttachedFile
|
||||
.builder()
|
||||
.fileName(tempFile.getName())
|
||||
.file(tempFile)
|
||||
.build();
|
||||
MessageToSend messageToSend = MessageToSend
|
||||
.builder()
|
||||
.fileToSend(tempFile)
|
||||
.attachedFiles(Arrays.asList(attachedFile))
|
||||
.build();
|
||||
return sendMessageToSendToChannel(messageToSend, channel);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import dev.sheldan.abstracto.core.service.management.DefaultEmoteManagementServi
|
||||
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.MessageReaction;
|
||||
@@ -164,7 +165,12 @@ public class EmoteServiceBean implements EmoteService {
|
||||
public AEmote getFakeEmoteFromEmote(Emote emote) {
|
||||
AServer server = null;
|
||||
if(emote.getGuild() != null) {
|
||||
server = AServer.builder().id(emote.getGuild().getIdLong()).fake(true).build();
|
||||
server = AServer
|
||||
.builder()
|
||||
.id(emote.getGuild()
|
||||
.getIdLong())
|
||||
.fake(true)
|
||||
.build();
|
||||
}
|
||||
return AEmote
|
||||
.builder()
|
||||
@@ -177,6 +183,18 @@ public class EmoteServiceBean implements EmoteService {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AEmote getFakeEmoteFromEmoji(Emoji emoji) {
|
||||
return AEmote
|
||||
.builder()
|
||||
.fake(true)
|
||||
.emoteKey(emoji.getName())
|
||||
.custom(emoji.isCustom())
|
||||
.animated(emoji.isAnimated())
|
||||
.emoteId(emoji.getIdLong())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean emoteIsFromGuild(Emote emote, Guild guild) {
|
||||
return guild.getEmoteById(emote.getId()) != null;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
@@ -7,6 +8,7 @@ import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.AttachedFile;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -14,9 +16,13 @@ import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.interactions.Interaction;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionComponent;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.requests.restaction.WebhookMessageAction;
|
||||
import net.dv8tion.jda.api.requests.restaction.WebhookMessageUpdateAction;
|
||||
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
|
||||
import net.dv8tion.jda.api.utils.AttachmentOption;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -57,7 +63,7 @@ public class InteractionServiceBean implements InteractionService {
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Message>> sendMessageToInteraction(MessageToSend messageToSend, InteractionHook interactionHook){
|
||||
public List<CompletableFuture<Message>> sendMessageToInteraction(MessageToSend messageToSend, InteractionHook interactionHook) {
|
||||
List<CompletableFuture<Message>> futures = new ArrayList<>();
|
||||
List<WebhookMessageAction<Message>> allMessageActions = new ArrayList<>();
|
||||
int iterations = Math.min(messageToSend.getMessages().size(), messageToSend.getEmbeds().size());
|
||||
@@ -105,13 +111,21 @@ public class InteractionServiceBean implements InteractionService {
|
||||
metricService.incrementCounter(EPHEMERAL_MESSAGES_SEND);
|
||||
}
|
||||
|
||||
if(messageToSend.hasFileToSend()) {
|
||||
if(messageToSend.hasFilesToSend()) {
|
||||
if(!allMessageActions.isEmpty()) {
|
||||
// in case there has not been a message, we need to increment it
|
||||
allMessageActions.set(0, allMessageActions.get(0).addFile(messageToSend.getFileToSend()));
|
||||
messageToSend.getAttachedFiles().forEach(attachedFile ->
|
||||
allMessageActions.set(0, allMessageActions.get(0).addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]))));
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
allMessageActions.add(interactionHook.sendFile(messageToSend.getFileToSend()));
|
||||
List<AttachedFile> attachedFiles = messageToSend.getAttachedFiles();
|
||||
AttachedFile firstFile = attachedFiles.get(0);
|
||||
allMessageActions.add(interactionHook.sendFile(firstFile.getFile(), firstFile.getFileName(), firstFile.getOptions().toArray(new AttachmentOption[0])));
|
||||
attachedFiles
|
||||
.stream()
|
||||
.skip(1)
|
||||
.forEach(attachedFile -> allMessageActions
|
||||
.add(interactionHook.sendFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]))));
|
||||
}
|
||||
}
|
||||
Set<Message.MentionType> allowedMentions = allowedMentionService.getAllowedMentionsFor(interactionHook.getInteraction().getMessageChannel(), messageToSend);
|
||||
@@ -125,6 +139,188 @@ public class InteractionServiceBean implements InteractionService {
|
||||
return sendMessageToInteraction(messageToSend, interactionHook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<InteractionHook> replyEmbed(String templateKey, Object model, IReplyCallback callback) {
|
||||
Long serverId = callback.getGuild().getIdLong();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(templateKey, model, serverId);
|
||||
return replyMessageToSend(messageToSend, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<InteractionHook> replyEmbed(String templateKey, IReplyCallback callback) {
|
||||
return replyEmbed(templateKey, new Object(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> editOriginal(MessageToSend messageToSend, InteractionHook interactionHook) {
|
||||
Long serverId = interactionHook.getInteraction().getGuild().getIdLong();
|
||||
|
||||
if(messageToSend.getEphemeral()) {
|
||||
Interaction interaction = interactionHook.getInteraction();
|
||||
log.info("Sending ephemeral message to interaction in guild {} in channel {} for user {}.",
|
||||
interaction.getGuild().getIdLong(), interaction.getChannel().getId(),
|
||||
interaction.getMember().getIdLong());
|
||||
metricService.incrementCounter(EPHEMERAL_MESSAGES_SEND);
|
||||
interactionHook.setEphemeral(true);
|
||||
}
|
||||
|
||||
WebhookMessageUpdateAction<Message> action = null;
|
||||
if(messageToSend.getMessages() != null && !messageToSend.getMessages().isEmpty()) {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
action = interactionHook.editOriginal(messageToSend.getMessages().get(0));
|
||||
}
|
||||
|
||||
if(messageToSend.getEmbeds() != null && !messageToSend.getEmbeds().isEmpty()) {
|
||||
if(action != null) {
|
||||
action = action.setEmbeds(messageToSend.getEmbeds().subList(0, 10));
|
||||
} else {
|
||||
action = interactionHook.editOriginalEmbeds(messageToSend.getEmbeds());
|
||||
}
|
||||
}
|
||||
|
||||
if(messageToSend.hasFilesToSend()) {
|
||||
if(action != null) {
|
||||
List<AttachedFile> attachedFiles = messageToSend.getAttachedFiles();
|
||||
AttachedFile firstFile = attachedFiles.get(0);
|
||||
action = action.addFile(firstFile.getFile(), firstFile.getFileName(), firstFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
boolean first = true;
|
||||
for (AttachedFile attachedFile : attachedFiles) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
action = action.addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
}
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
List<AttachedFile> attachedFiles = messageToSend.getAttachedFiles();
|
||||
AttachedFile firstFile = attachedFiles.get(0);
|
||||
action = interactionHook.editOriginal(firstFile.getFile(), firstFile.getFileName(), firstFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
boolean first = true;
|
||||
for (AttachedFile attachedFile : attachedFiles) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
action = action.addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this should be last, because we are "faking" a message, by inserting a ., in case there has not been a reply yet
|
||||
// we could also throw an exception, but we are allowing this to go through
|
||||
List<ActionRow> actionRows = messageToSend.getActionRows();
|
||||
if(actionRows != null && !actionRows.isEmpty()) {
|
||||
if(action == null) {
|
||||
action = interactionHook.editOriginal(".");
|
||||
}
|
||||
action = action.setActionRows(actionRows);
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
actionRows.forEach(components -> components.forEach(component -> {
|
||||
if(component instanceof ActionComponent) {
|
||||
String id = ((ActionComponent)component).getId();
|
||||
MessageToSend.ComponentConfig payload = messageToSend.getComponentPayloads().get(id);
|
||||
if(payload.getPersistCallback()) {
|
||||
componentPayloadManagementService.createPayload(id, payload.getPayload(), payload.getPayloadType(), payload.getComponentOrigin(), server, payload.getComponentType());
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if(action == null) {
|
||||
throw new AbstractoRunTimeException("The callback did not result in any message.");
|
||||
}
|
||||
return action.submit();
|
||||
}
|
||||
|
||||
public CompletableFuture<InteractionHook> replyMessageToSend(MessageToSend messageToSend, IReplyCallback callback) {
|
||||
Long serverId = callback.getGuild().getIdLong();
|
||||
ReplyCallbackAction action = null;
|
||||
if(messageToSend.getMessages() != null && !messageToSend.getMessages().isEmpty()) {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
action = callback.reply(messageToSend.getMessages().get(0));
|
||||
}
|
||||
|
||||
if(messageToSend.getEmbeds() != null && !messageToSend.getEmbeds().isEmpty()) {
|
||||
if(action != null) {
|
||||
action = action.addEmbeds(messageToSend.getEmbeds().subList(0, 10));
|
||||
} else {
|
||||
action = callback.replyEmbeds(messageToSend.getEmbeds());
|
||||
}
|
||||
}
|
||||
|
||||
if(messageToSend.hasFilesToSend()) {
|
||||
if(action != null) {
|
||||
List<AttachedFile> attachedFiles = messageToSend.getAttachedFiles();
|
||||
AttachedFile firstFile = attachedFiles.get(0);
|
||||
action = action.addFile(firstFile.getFile(), firstFile.getFileName(), firstFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
boolean first = true;
|
||||
for (AttachedFile attachedFile : attachedFiles) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
action = action.addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
}
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_SEND_METRIC);
|
||||
List<AttachedFile> attachedFiles = messageToSend.getAttachedFiles();
|
||||
AttachedFile firstFile = attachedFiles.get(0);
|
||||
action = callback.replyFile(firstFile.getFile(), firstFile.getFileName(), firstFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
boolean first = true;
|
||||
for (AttachedFile attachedFile : attachedFiles) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
action = action.addFile(attachedFile.getFile(), attachedFile.getFileName(), attachedFile.getOptions().toArray(new AttachmentOption[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this should be last, because we are "faking" a message, by inserting a ., in case there has not been a reply yet
|
||||
// we could also throw an exception, but we are allowing this to go through
|
||||
List<ActionRow> actionRows = messageToSend.getActionRows();
|
||||
if(actionRows != null && !actionRows.isEmpty()) {
|
||||
if(action == null) {
|
||||
action = callback.reply(".");
|
||||
}
|
||||
action = action.addActionRows(actionRows);
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
actionRows.forEach(components -> components.forEach(component -> {
|
||||
if(component instanceof ActionComponent) {
|
||||
String id = ((ActionComponent)component).getId();
|
||||
MessageToSend.ComponentConfig payload = messageToSend.getComponentPayloads().get(id);
|
||||
if(payload.getPersistCallback()) {
|
||||
componentPayloadManagementService.createPayload(id, payload.getPayload(), payload.getPayloadType(), payload.getComponentOrigin(), server, payload.getComponentType());
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if(messageToSend.getEphemeral()) {
|
||||
log.info("Sending ephemeral message to interaction in guild {} in channel {} for user {}.",
|
||||
callback.getGuild().getIdLong(), callback.getChannel().getId(),
|
||||
callback.getMember().getIdLong());
|
||||
metricService.incrementCounter(EPHEMERAL_MESSAGES_SEND);
|
||||
if(action != null) {
|
||||
action = action.setEphemeral(messageToSend.getEphemeral());
|
||||
}
|
||||
}
|
||||
|
||||
if(action == null) {
|
||||
throw new AbstractoRunTimeException("The callback did not result in any message.");
|
||||
}
|
||||
return action.submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<InteractionHook> replyMessage(String templateKey, Object model, IReplyCallback callback) {
|
||||
Long serverId = callback.getGuild().getIdLong();
|
||||
MessageToSend messageToSend = templateService.renderTemplateToMessageToSend(templateKey, model, serverId);
|
||||
return replyMessageToSend(messageToSend, callback);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(EPHEMERAL_MESSAGES_SEND, "Ephemeral messages send");
|
||||
|
||||
@@ -73,6 +73,12 @@ public class MessageServiceBean implements MessageService {
|
||||
.tagList(Arrays.asList(MetricTag.getTag(INTERACTION_TYPE, "message.delete")))
|
||||
.build();
|
||||
|
||||
public static final CounterMetric MESSAGE_PIN_METRIC = CounterMetric
|
||||
.builder()
|
||||
.name(DISCORD_API_INTERACTION_METRIC)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(INTERACTION_TYPE, "message.pin")))
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteMessageInChannelInServer(Long serverId, Long channelId, Long messageId) {
|
||||
metricService.incrementCounter(MESSAGE_DELETE_METRIC);
|
||||
@@ -251,11 +257,18 @@ public class MessageServiceBean implements MessageService {
|
||||
return message.editMessage(message).setActionRows(rows).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> pinMessage(Message message) {
|
||||
metricService.incrementCounter(MESSAGE_PIN_METRIC);
|
||||
return message.pin().submit();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(MESSAGE_SEND_METRIC, "Messages send to discord");
|
||||
metricService.registerCounter(MESSAGE_EDIT_METRIC, "Messages edited in discord");
|
||||
metricService.registerCounter(MESSAGE_LOAD_METRIC, "Messages loaded from discord");
|
||||
metricService.registerCounter(MESSAGE_DELETE_METRIC, "Messages deleted from discord");
|
||||
metricService.registerCounter(MESSAGE_PIN_METRIC, "Messages pinned in discord");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.model.PaginatorButtonPayload;
|
||||
import dev.sheldan.abstracto.core.model.PaginatorConfiguration;
|
||||
import dev.sheldan.abstracto.core.model.PaginatorFooterModel;
|
||||
@@ -22,7 +23,7 @@ import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -38,9 +39,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
@Slf4j
|
||||
public class PaginatorServiceBean implements PaginatorService {
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@@ -68,6 +66,9 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
@Autowired
|
||||
private SchedulerService schedulerService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
private static final Map<String, PaginatorInfo> PAGINATORS = new ConcurrentHashMap<>();
|
||||
public static final String PAGINATOR_BUTTON = "PAGINATOR_BUTTON";
|
||||
public static final String PAGINATOR_FOOTER_TEMPLATE_KEY = "paginator_footer";
|
||||
@@ -76,6 +77,15 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
@Override
|
||||
public CompletableFuture<Void> createPaginatorFromTemplate(String templateKey, Object model, GuildMessageChannel textChannel, Long userId) {
|
||||
Long serverId = textChannel.getGuild().getIdLong();
|
||||
PaginatorSetup setup = getPaginatorSetup(templateKey, model, userId, serverId);
|
||||
log.info("Setting up paginator in channel {} in server {} with {} pages.", textChannel.getIdLong(),
|
||||
textChannel.getGuild().getIdLong(), setup.getConfiguration().getEmbedConfigs().size());
|
||||
List<CompletableFuture<Message>> paginatorFutures = channelService.sendMessageToSendToChannel(setup.getMessageToSend(), textChannel);
|
||||
return FutureUtils.toSingleFutureGeneric(paginatorFutures)
|
||||
.thenAccept(unused -> self.setupButtonPayloads(paginatorFutures.get(0).join(), setup, serverId));
|
||||
}
|
||||
|
||||
private PaginatorSetup getPaginatorSetup(String templateKey, Object model, Long userId, Long serverId) {
|
||||
String exitButtonId = componentService.generateComponentId(serverId);
|
||||
String startButtonId = componentService.generateComponentId(serverId);
|
||||
String previousButtonId = componentService.generateComponentId(serverId);
|
||||
@@ -92,8 +102,6 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
.build();
|
||||
String embedConfig = templateService.renderTemplate(templateKey + "_paginator", wrapperModel, serverId);
|
||||
PaginatorConfiguration configuration = gson.fromJson(embedConfig, PaginatorConfiguration.class);
|
||||
log.info("Setting up paginator in channel {} in server {} with {} pages.", textChannel.getIdLong(),
|
||||
textChannel.getGuild().getIdLong(), configuration.getEmbedConfigs().size());
|
||||
setupFooters(configuration);
|
||||
|
||||
configuration.setPaginatorId(componentService.generateComponentId());
|
||||
@@ -113,9 +121,21 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
|
||||
MessageConfiguration messageConfiguration = configuration.getEmbedConfigs().get(0);
|
||||
MessageToSend messageToSend = templateServiceBean.convertEmbedConfigurationToMessageToSend(messageConfiguration);
|
||||
List<CompletableFuture<Message>> paginatorFutures = channelService.sendMessageToSendToChannel(messageToSend, textChannel);
|
||||
return FutureUtils.toSingleFutureGeneric(paginatorFutures)
|
||||
.thenAccept(unused -> self.setupButtonPayloads(paginatorFutures.get(0).join(), configuration, serverId, buttonPayload));
|
||||
return PaginatorSetup
|
||||
.builder()
|
||||
.messageToSend(messageToSend)
|
||||
.configuration(configuration)
|
||||
.payload(buttonPayload)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createPaginatorFromTemplate(String templateKey, Object model, IReplyCallback callback) {
|
||||
Long serverId = callback.getGuild().getIdLong();
|
||||
PaginatorSetup setup = getPaginatorSetup(templateKey, model, callback.getMember().getIdLong(), serverId);
|
||||
return interactionService.replyMessageToSend(setup.getMessageToSend(), callback)
|
||||
.thenCompose(interactionHook -> interactionHook.retrieveOriginal().submit())
|
||||
.thenAccept(message -> self.setupButtonPayloads(message, setup, serverId));
|
||||
}
|
||||
|
||||
private void setupFooters(PaginatorConfiguration configuration) {
|
||||
@@ -219,7 +239,9 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void setupButtonPayloads(Message paginatorMessage, PaginatorConfiguration configuration, Long serverId, PaginatorButtonPayload payload) {
|
||||
public void setupButtonPayloads(Message paginatorMessage, PaginatorSetup setup, Long serverId) {
|
||||
PaginatorConfiguration configuration = setup.getConfiguration();
|
||||
PaginatorButtonPayload payload = setup.getPayload();
|
||||
savePayload(configuration.getExitButton(), serverId);
|
||||
if(!configuration.getSinglePage()) {
|
||||
savePayload(configuration.getStartButton(), serverId);
|
||||
@@ -274,4 +296,12 @@ public class PaginatorServiceBean implements PaginatorService {
|
||||
private List<String> payloadIds;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public static class PaginatorSetup {
|
||||
private PaginatorConfiguration configuration;
|
||||
private PaginatorButtonPayload payload;
|
||||
private MessageToSend messageToSend;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package dev.sheldan.abstracto.core.startup;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.slash.SlashCommandService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.listener.AsyncStartupListener;
|
||||
import dev.sheldan.abstracto.core.command.SlashCommandListenerBean;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SlashCommandLoaderListener implements AsyncStartupListener {
|
||||
|
||||
@Autowired
|
||||
private SlashCommandListenerBean slashCommandListenerBean;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandService slashCommandService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<Command> incomingSlashCommands = slashCommandListenerBean.getSlashCommands();
|
||||
JDA jda = botService.getInstance();
|
||||
List<Guild> onlineGuilds = jda.getGuilds();
|
||||
onlineGuilds.forEach(guild -> {
|
||||
log.info("Updating slash commands for guild {}.", guild.getIdLong());
|
||||
guild.retrieveCommands().queue(commands -> {
|
||||
log.info("Loaded {} slash commands for guild {}.", commands.size(), guild.getIdLong());
|
||||
List<Pair<List<CommandConfiguration>, SlashCommandData>> commandsToUpDate = new ArrayList<>();
|
||||
incomingSlashCommands.forEach(command -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(command.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, guild.getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(command, guild.getIdLong())) {
|
||||
return;
|
||||
}
|
||||
log.info("Updating slash command {} in guild {}.", command.getConfiguration().getName(), guild.getId());
|
||||
slashCommandService.convertCommandConfigToCommandData(command.getConfiguration(), commandsToUpDate);
|
||||
});
|
||||
slashCommandService.updateGuildSlashCommand(guild, commandsToUpDate)
|
||||
.thenAccept(commands1 -> log.info("Updated {} commands in guild {}.", commands1.size(), guild.getIdLong()));
|
||||
},
|
||||
throwable -> log.error("Failed to load commands for guild {}.", guild.getIdLong(), throwable));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.core.templating.model;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class FileConfig {
|
||||
private String fileName;
|
||||
private Boolean spoiler;
|
||||
}
|
||||
@@ -22,4 +22,5 @@ public class MessageConfiguration {
|
||||
private String additionalMessage;
|
||||
private MetaMessageConfiguration messageConfig;
|
||||
private List<ButtonConfig> buttons;
|
||||
private List<FileConfig> files;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
import net.dv8tion.jda.api.utils.AttachmentOption;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -166,6 +168,22 @@ public class TemplateServiceBean implements TemplateService {
|
||||
isEphemeral = Boolean.TRUE.equals(messageConfiguration.getMessageConfig().isEphemeral());
|
||||
}
|
||||
|
||||
List<AttachedFile> files = new ArrayList<>();
|
||||
if(messageConfiguration.getFiles() != null && !messageConfiguration.getFiles().isEmpty()) {
|
||||
messageConfiguration.getFiles().forEach(fileToAttach -> {
|
||||
List<AttachmentOption> options = new ArrayList<>();
|
||||
if(fileToAttach.getSpoiler() != null && fileToAttach.getSpoiler()) {
|
||||
options.add(AttachmentOption.SPOILER);
|
||||
}
|
||||
AttachedFile attachedFile = AttachedFile
|
||||
.builder()
|
||||
.fileName(fileToAttach.getFileName() != null ? fileToAttach.getFileName() : RandomStringUtils.randomAlphabetic(5))
|
||||
.options(options)
|
||||
.build();
|
||||
files.add(attachedFile);
|
||||
});
|
||||
}
|
||||
|
||||
String additionalMessage = messageConfiguration.getAdditionalMessage();
|
||||
if(additionalMessage != null) {
|
||||
Long segmentLimit = messageConfiguration.getMessageConfig() != null
|
||||
@@ -212,6 +230,7 @@ public class TemplateServiceBean implements TemplateService {
|
||||
.messageConfig(createMessageConfig(messageConfiguration.getMessageConfig()))
|
||||
.messages(messages)
|
||||
.ephemeral(isEphemeral)
|
||||
.attachedFiles(!files.isEmpty() ? files : null)
|
||||
.actionRows(buttons)
|
||||
.componentPayloads(componentPayloads)
|
||||
.referencedMessageId(referencedMessageId)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.utils;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.SnowFlake;
|
||||
import net.dv8tion.jda.api.entities.ISnowflake;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SnowflakeUtils {
|
||||
private SnowflakeUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static Set<Long> getOwnItemsIds(List<? extends SnowFlake> elements){
|
||||
return elements.stream().map(SnowFlake::getId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Set<Long> getSnowflakeIds(List<? extends ISnowflake> elements){
|
||||
return elements.stream().map(ISnowflake::getIdLong).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="command_in_server-add-slash-command-id">
|
||||
<addColumn tableName="command_in_server" >
|
||||
<column name="slash_command_id" type="BIGINT">
|
||||
<constraints nullable="true" />
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -8,4 +8,5 @@
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="channel.xml" relativeToChangelogFile="true"/>
|
||||
<include file="component_payload.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command_in_server.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user