moved commands into the core, because its a core functionality

This commit is contained in:
Sheldan
2020-04-04 18:08:55 +02:00
parent a957c66905
commit 9b46f8d187
90 changed files with 352 additions and 407 deletions

View File

@@ -0,0 +1,93 @@
package dev.sheldan.abstracto.core.command;
import dev.sheldan.abstracto.core.command.exception.CommandNotFound;
import dev.sheldan.abstracto.core.command.exception.InsufficientParameters;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.meta.CommandRegistry;
import dev.sheldan.abstracto.core.command.meta.UnParsedCommandParameter;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class CommandManager implements CommandRegistry {
@Autowired
private List<Command> commands;
@Override
public Command findCommandByParameters(String name, UnParsedCommandParameter unParsedCommandParameter) {
Optional<Command> commandOptional = commands.stream().filter((Command o )-> {
CommandConfiguration commandConfiguration = o.getConfiguration();
if(!commandNameMatches(name, commandConfiguration)) {
return false;
}
boolean parameterFit;
if(commandConfiguration.getParameters() != null){
boolean paramCountFits = unParsedCommandParameter.getParameters().size() >= commandConfiguration.getNecessaryParameterCount();
boolean hasRemainderParameter = commandConfiguration.getParameters().stream().anyMatch(Parameter::isRemainder);
if(unParsedCommandParameter.getParameters().size() < commandConfiguration.getNecessaryParameterCount()) {
String nextParameterName = commandConfiguration.getParameters().get(commandConfiguration.getNecessaryParameterCount() - 1).getName();
throw new InsufficientParameters("Insufficient parameters", o, nextParameterName);
}
parameterFit = paramCountFits || hasRemainderParameter;
} else {
parameterFit = unParsedCommandParameter.getParameters().size() == 0;
}
return parameterFit;
}).findFirst();
if(commandOptional.isPresent()){
return commandOptional.get();
}
throw new CommandNotFound("Command not found.");
}
private boolean commandNameMatches(String name, CommandConfiguration commandConfiguration) {
boolean commandNameMatches = commandConfiguration.getName().equalsIgnoreCase(name);
if(commandNameMatches) {
return true;
}
boolean aliasesMatch = false;
if(commandConfiguration.getAliases() != null) {
aliasesMatch = commandConfiguration.getAliases().stream().anyMatch(s -> s.equalsIgnoreCase(name));
}
return aliasesMatch;
}
public Command findCommand(String name) {
Optional<Command> commandOptional = commands.stream().filter((Command o )-> {
CommandConfiguration commandConfiguration = o.getConfiguration();
return commandConfiguration.getName().equals(name);
}).findFirst();
if(commandOptional.isPresent()){
return commandOptional.get();
}
throw new CommandNotFound("Command not found.");
}
@Override
public List<Command> getAllCommands() {
return commands;
}
@Override
public List<Command> getAllCommandsFromModule(ModuleInterface moduleInterface) {
List<Command> commands = new ArrayList<>();
this.getAllCommands().forEach(command -> {
if(command.getConfiguration().getModule().equals(moduleInterface.getInfo().getName())){
commands.add(command);
}
});
return commands;
}
@Override
public boolean isCommand(Message message) {
return message.getContentRaw().startsWith("!");
}
}

View File

@@ -0,0 +1,198 @@
package dev.sheldan.abstracto.core.command;
import dev.sheldan.abstracto.core.command.exception.IncorrectParameter;
import dev.sheldan.abstracto.core.command.exception.ParameterTooLong;
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.command.meta.UnParsedCommandParameter;
import dev.sheldan.abstracto.core.Constants;
import dev.sheldan.abstracto.core.exception.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.utils.ParseUtils;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@Service
@Slf4j
public class CommandReceivedHandler extends ListenerAdapter {
@Autowired
private CommandManager commandManager;
@Autowired
private List<PostCommandExecution> executions;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
@Lazy
private CommandReceivedHandler self;
@Override
@Async
@Transactional
public void onMessageReceived(@Nonnull MessageReceivedEvent event) {
if(!commandManager.isCommand(event.getMessage())) {
return;
}
if(!event.isFromGuild()) {
return;
}
CommandContext.CommandContextBuilder commandContextBuilder = CommandContext.builder()
.author(event.getMember())
.guild(event.getGuild())
.channel(event.getTextChannel())
.message(event.getMessage())
.jda(event.getJDA())
.userInitiatedContext(buildTemplateParameter(event));
Command foundCommand = null;
try {
String contentStripped = event.getMessage().getContentStripped();
List<String> parameters = Arrays.asList(contentStripped.split(" "));
UnParsedCommandParameter unparsedParameter = new UnParsedCommandParameter(contentStripped);
String commandName = parameters.get(0).substring(1);
foundCommand = commandManager.findCommandByParameters(commandName, unparsedParameter);
Parameters parsedParameters = getParsedParameters(unparsedParameter, foundCommand, event.getMessage());
CommandContext commandContext = commandContextBuilder.parameters(parsedParameters).build();
if(foundCommand instanceof ConditionalCommand) {
ConditionalCommand castedCommand = (ConditionalCommand) foundCommand;
if (!shouldExecute(commandContext, foundCommand, castedCommand.getConditions())) {
throw new FeatureDisabledException(String.format("Feature `%s` has been disabled. Command is not usable", foundCommand.getFeature()));
}
}
CommandResult commandResult = self.executeCommand(foundCommand, commandContext);
for (PostCommandExecution postCommandExecution : executions) {
postCommandExecution.execute(commandContext, commandResult, foundCommand);
}
} catch (Exception e) {
CommandResult commandResult = CommandResult.fromError(e.getMessage(), e);
CommandContext commandContext = commandContextBuilder.build();
for (PostCommandExecution postCommandExecution : executions) {
postCommandExecution.execute(commandContext, commandResult, foundCommand);
}
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public CommandResult executeCommand(Command foundCommand, CommandContext commandContext) {
return foundCommand.execute(commandContext);
}
public boolean shouldExecute(CommandContext commandContext, Command command, List<CommandCondition> conditions) {
AtomicBoolean shouldExecute = new AtomicBoolean(true);
if(conditions != null) {
conditions.forEach(condition -> {
shouldExecute.set(shouldExecute.get() && condition.shouldExecute(commandContext, command));
});
}
return shouldExecute.get();
}
private UserInitiatedServerContext buildTemplateParameter(MessageReceivedEvent event) {
AChannel channel = channelManagementService.loadChannel(event.getChannel().getIdLong());
AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong());
AUserInAServer user = userManagementService.loadUser(event.getMember());
return UserInitiatedServerContext
.builder()
.channel(channel)
.server(server)
.member(event.getMember())
.aUserInAServer(user)
.user(user.getUserReference())
.messageChannel(event.getTextChannel())
.guild(event.getGuild())
.build();
}
public Parameters getParsedParameters(UnParsedCommandParameter unParsedCommandParameter, Command command, Message message){
List<Object> parsedParameters = new ArrayList<>();
if(command.getConfiguration().getParameters().size() == 0) {
return Parameters.builder().parameters(parsedParameters).build();
}
Iterator<TextChannel> channelIterator = message.getMentionedChannels().iterator();
Iterator<Emote> emoteIterator = message.getEmotes().iterator();
Iterator<Member> memberIterator = message.getMentionedMembers().iterator();
Parameter param = command.getConfiguration().getParameters().get(0);
boolean reminderActive = false;
for (int i = 0; i < unParsedCommandParameter.getParameters().size(); i++) {
if(i < command.getConfiguration().getParameters().size() && !param.isRemainder()) {
param = command.getConfiguration().getParameters().get(i);
} else {
reminderActive = true;
}
String value = unParsedCommandParameter.getParameters().get(i);
if(param.getMaxLength() != null && (value.length() + Constants.PARAMETER_LIMIT) > param.getMaxLength()) {
throw new ParameterTooLong("The passed parameter was too long.", command, param.getName(), value.length(), param.getMaxLength());
}
try {
if(param.getType().equals(Integer.class)){
parsedParameters.add(Integer.parseInt(value));
} else if(param.getType().equals(Double.class)){
parsedParameters.add(Double.parseDouble(value));
} else if(param.getType().equals(Long.class)){
parsedParameters.add(Long.parseLong(value));
} else if(param.getType().equals(TextChannel.class)){
parsedParameters.add(channelIterator.next());
} else if(param.getType().equals(Member.class)) {
parsedParameters.add(memberIterator.next());
} else if(param.getType().equals(Emote.class)) {
// TODO maybe rework, this fails if two emotes are needed, and the second one is an emote, the first one a default one
// the second one shadows the first one, and there are too little parameters to go of
if (emoteIterator.hasNext()) {
parsedParameters.add(emoteIterator.next());
} else {
parsedParameters.add(value);
}
} else if(param.getType().equals(Boolean.class)) {
parsedParameters.add(Boolean.valueOf(value));
} else if (param.getType().equals(Duration.class)) {
parsedParameters.add(ParseUtils.parseDuration(value));
} else {
if(!reminderActive) {
parsedParameters.add(value);
} else {
if(parsedParameters.size() == 0) {
parsedParameters.add(value);
} else {
int lastIndex = parsedParameters.size() - 1;
parsedParameters.set(lastIndex, parsedParameters.get(lastIndex) + " " + value);
}
}
}
} catch (NoSuchElementException e) {
throw new IncorrectParameter("The passed parameters did not have the correct type.", command, param.getType(), param.getName());
}
}
return Parameters.builder().parameters(parsedParameters).build();
}
}

View File

@@ -0,0 +1,87 @@
package dev.sheldan.abstracto.core.command;
import dev.sheldan.abstracto.core.command.meta.CommandRegistry;
import dev.sheldan.abstracto.core.command.service.ModuleRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ModuleManager implements ModuleRegistry {
@Autowired
private List<ModuleInterface> moduleInterfaces;
@Autowired
private CommandRegistry commandRegistry;
@Override
public CommandHierarchy getDetailedModules() {
List<PackedModule> modulesWithCommands = new ArrayList<>();
List<ModuleInterface> currentModuleInterfaces = getModuleInterfaces();
currentModuleInterfaces.forEach(module -> {
List<Command> commands = commandRegistry.getAllCommandsFromModule(module);
PackedModule packed = PackedModule.builder().commands(commands).moduleInterface(module).subModules(new ArrayList<>()).build();
modulesWithCommands.add(packed);
});
return getHierarchicalPacks(modulesWithCommands, currentModuleInterfaces);
}
private CommandHierarchy getHierarchicalPacks(List<PackedModule> modules, List<ModuleInterface> currentModuleInterfaces){
List<PackedModule> hierarchical = modules.stream().filter(packedModule -> packedModule.getModuleInterface().getParentModule() == null).collect(Collectors.toList());
List<PackedModule> subModules = modules.stream().filter(packedModule -> packedModule.getModuleInterface().getParentModule() != null).collect(Collectors.toList());
subModules.forEach(module -> {
List<ModuleInterface> path = getModulePath(module, currentModuleInterfaces);
Collections.reverse(path);
ModuleInterface rootModuleInterface = path.get(0);
Optional<PackedModule> any = hierarchical.stream().filter(moduleInList -> moduleInList.getModuleInterface().getInfo().getName().equals(rootModuleInterface.getInfo().getName())).findAny();
if(any.isPresent()){
PackedModule currentNodeInHierarchy = any.get();
for (int i = 1; i < path.size(); i++) {
Optional<PackedModule> nextInHierarchy = currentNodeInHierarchy.getSubModules().stream().filter(module1 -> module1.getModuleInterface().equals(module.getModuleInterface())).findAny();
if(nextInHierarchy.isPresent()){
currentNodeInHierarchy = nextInHierarchy.get();
} else {
currentNodeInHierarchy.getSubModules().add(module);
currentNodeInHierarchy = module;
}
}
if(path.size() == 1){
currentNodeInHierarchy.getSubModules().add(module);
}
}
});
return CommandHierarchy.builder().rootModules(hierarchical).build();
}
private List<ModuleInterface> getModulePath(PackedModule moduleToPathFor, List<ModuleInterface> currentModuleInterfaces){
List<ModuleInterface> modulesBetweenRootAndThis = new ArrayList<>();
ModuleInterface current = moduleToPathFor.getModuleInterface();
modulesBetweenRootAndThis.add(current);
while(current.getParentModule() != null){
String parentModule = current.getParentModule();
Optional<ModuleInterface> possibleModule = currentModuleInterfaces.stream().filter(module1 -> module1.getInfo().getName().equals(parentModule)).findFirst();
if(possibleModule.isPresent()){
ModuleInterface foundModuleInterface = possibleModule.get();
modulesBetweenRootAndThis.add(foundModuleInterface);
current = foundModuleInterface;
} else {
break;
}
}
return modulesBetweenRootAndThis;
}
@Override
public List<ModuleInterface> getModuleInterfaces() {
return moduleInterfaces;
}
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.abstracto.core.command.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:commands.properties")
public class CommandConfig {
}

View File

@@ -0,0 +1,29 @@
package dev.sheldan.abstracto.core.command.config;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.service.CommandService;
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class CommandConfigListener implements ServerConfigListener {
@Autowired
private List<Command> commandList;
@Autowired
private CommandService commandService;
@Override
public void updateServerConfig(AServer server) {
commandList.forEach(command -> {
if(!commandService.doesCommandExist(command.getConfiguration().getName())) {
commandService.createCommand(command.getConfiguration().getName(), command.getConfiguration().getModule());
}
});
}
}

View File

@@ -0,0 +1,21 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
public class CommandNotFound extends AbstractoRunTimeException implements Templatable {
public CommandNotFound(String s) {
super(s);
}
@Override
public String getTemplateName() {
return "command_not_found";
}
@Override
public Object getTemplateModel() {
return null;
}
}

View File

@@ -0,0 +1,34 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import java.util.HashMap;
public class IncorrectParameter extends AbstractoRunTimeException implements Templatable {
private Command command;
private String parameterName;
private Class clazz;
public IncorrectParameter(String s, Command command, Class expected, String parameterName) {
super(s);
this.command = command;
this.parameterName = parameterName;
this.clazz = expected;
}
@Override
public String getTemplateName() {
return "incorrect_parameters";
}
@Override
public Object getTemplateModel() {
HashMap<String, Object> model = new HashMap<>();
model.put("parameterName", parameterName);
model.put("class", this.clazz);
return model;
}
}

View File

@@ -0,0 +1,33 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Templatable;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import lombok.Getter;
import java.util.HashMap;
@Getter
public class InsufficientParameters extends AbstractoRunTimeException implements Templatable {
private Command command;
private String parameterName;
public InsufficientParameters(String s, Command command, String parameterName) {
super(s);
this.command = command;
this.parameterName = parameterName;
}
@Override
public String getTemplateName() {
return "insufficient_parameters";
}
@Override
public Object getTemplateModel() {
HashMap<String, Object> model = new HashMap<>();
model.put("parameterName", parameterName);
return model;
}
}

View File

@@ -0,0 +1,39 @@
package dev.sheldan.abstracto.core.command.exception;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.Templatable;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import java.util.HashMap;
public class ParameterTooLong extends AbstractoRunTimeException implements Templatable {
private Command command;
private String parameterName;
private Integer actualLength;
private Integer maximumLength;
public ParameterTooLong(String s, Command command, String parameterName, Integer actualLength, Integer maximumLength) {
super(s);
this.command = command;
this.parameterName = parameterName;
this.actualLength = actualLength;
this.maximumLength = maximumLength;
}
@Override
public String getTemplateName() {
return "parameter_too_long";
}
@Override
public Object getTemplateModel() {
HashMap<String, Object> model = new HashMap<>();
model.put("parameterName", parameterName);
model.put("actualLength", actualLength);
model.put("maximumLength", maximumLength);
model.put("command", command);
return model;
}
}

View File

@@ -0,0 +1,41 @@
package dev.sheldan.abstracto.core.command.post;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
import dev.sheldan.abstracto.core.command.Templatable;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ResultState;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class ExceptionPostExecution implements PostCommandExecution {
@Autowired
private TemplateService templateService;
@Override
public void execute(CommandContext commandContext, CommandResult commandResult, Command command) {
if(commandResult.getResult().equals(ResultState.ERROR)) {
Throwable throwable = commandResult.getThrowable();
if(throwable != null) {
if(throwable instanceof Templatable) {
Templatable exception = (Templatable) throwable;
String text = templateService.renderTemplate(exception.getTemplateName(), exception.getTemplateModel());
commandContext.getChannel().sendMessage(text).queue();
} else {
if(throwable.getCause() == null) {
commandContext.getChannel().sendMessage(throwable.getClass().getSimpleName() + ": " + commandResult.getMessage()).queue();
} else {
Throwable cause = throwable.getCause();
commandContext.getChannel().sendMessage(throwable.getClass().getSimpleName() + ": " + commandResult.getMessage() + ": " + cause.getClass().getSimpleName() + ":" + cause.getMessage()).queue();
}
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
package dev.sheldan.abstracto.core.command.post;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ResultState;
import dev.sheldan.abstracto.core.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ReactionPostExecution implements PostCommandExecution {
public static final String WARN_REACTION_EMOTE = "warnReaction";
public static final String SUCCESS_REACTION_EMOTE = "successReaction";
@Autowired
private MessageService messageService;
@Override
public void execute(CommandContext commandContext, CommandResult commandResult, Command command) {
if(commandResult.getResult().equals(ResultState.ERROR)) {
messageService.addReactionToMessage(WARN_REACTION_EMOTE, commandContext.getGuild().getIdLong(), commandContext.getMessage());
if(commandResult.getMessage() != null && commandResult.getThrowable() == null){
commandContext.getChannel().sendMessage(commandResult.getMessage()).queue();
}
} else {
if(command.getConfiguration().isCausesReaction()){
messageService.addReactionToMessage(SUCCESS_REACTION_EMOTE, commandContext.getGuild().getIdLong(), commandContext.getMessage());
}
}
}
}

View File

@@ -0,0 +1,8 @@
package dev.sheldan.abstracto.core.command.repository;
import dev.sheldan.abstracto.core.command.models.ACommand;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CommandRepository extends JpaRepository<ACommand, Long> {
ACommand findByName(String name);
}

View File

@@ -0,0 +1,8 @@
package dev.sheldan.abstracto.core.command.repository;
import dev.sheldan.abstracto.core.command.models.AModule;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ModuleRepository extends JpaRepository<AModule, Long> {
AModule findByName(String name);
}

View File

@@ -0,0 +1,32 @@
package dev.sheldan.abstracto.core.command.service;
import dev.sheldan.abstracto.core.command.models.ACommand;
import dev.sheldan.abstracto.core.command.models.AModule;
import dev.sheldan.abstracto.core.command.service.CommandService;
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
import dev.sheldan.abstracto.core.command.service.management.ModuleManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CommandServiceBean implements CommandService {
@Autowired
private ModuleManagementService moduleManagementService;
@Autowired
private CommandManagementService commandManagementService;
@Override
public ACommand createCommand(String name, String moduleName) {
AModule module = moduleManagementService.getOrCreate(moduleName);
return commandManagementService.createCommand(name, module);
}
@Override
public Boolean doesCommandExist(String name) {
return commandManagementService.doesCommandExist(name);
}
}

View File

@@ -0,0 +1,49 @@
package dev.sheldan.abstracto.core.command.service.management;
import dev.sheldan.abstracto.core.command.models.ACommand;
import dev.sheldan.abstracto.core.command.models.AModule;
import dev.sheldan.abstracto.core.command.repository.CommandRepository;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CommandManagementServiceBean implements CommandManagementService {
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ModuleManagementService moduleManagementService;
@Autowired
private CommandRepository commandRepository;
@Override
public ACommand createCommand(String name, String moduleName) {
AModule module = moduleManagementService.findModuleByName(moduleName);
return createCommand(name, module);
}
@Override
public ACommand createCommand(String name, AModule module) {
ACommand command = ACommand
.builder()
.name(name)
.module(module)
.build();
commandRepository.save(command);
return command;
}
@Override
public ACommand findCommandByName(String name) {
return commandRepository.findByName(name);
}
@Override
public Boolean doesCommandExist(String name) {
return findCommandByName(name) != null;
}
}

View File

@@ -0,0 +1,42 @@
package dev.sheldan.abstracto.core.command.service.management;
import dev.sheldan.abstracto.core.command.models.AModule;
import dev.sheldan.abstracto.core.command.repository.ModuleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ModuleManagementServiceBean implements ModuleManagementService {
@Autowired
private ModuleRepository moduleRepository;
@Override
public AModule createModule(String name) {
AModule module = AModule.
builder()
.name(name)
.build();
moduleRepository.save(module);
return module;
}
@Override
public AModule getOrCreate(String name) {
AModule module = findModuleByName(name);
if(module == null) {
return createModule(name);
}
return module;
}
@Override
public AModule findModuleByName(String name) {
return moduleRepository.findByName(name);
}
@Override
public Boolean doesModuleExist(String name) {
return findModuleByName(name) != null;
}
}

View File

@@ -1,12 +1,12 @@
package dev.sheldan.abstracto.core.commands;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.commands.utility.UtilityModule;
import dev.sheldan.abstracto.core.commands.utility.UtilityModuleInterface;
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -33,7 +33,7 @@ public class Disable implements Command {
List<Parameter> parameters = Arrays.asList(featureName);
return CommandConfiguration.builder()
.name("disable")
.module(UtilityModule.UTILITY)
.module(UtilityModuleInterface.UTILITY)
.parameters(parameters)
.description("Disables features for this server.")
.causesReaction(true)

View File

@@ -1,12 +1,12 @@
package dev.sheldan.abstracto.core.commands;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.commands.utility.UtilityModule;
import dev.sheldan.abstracto.core.commands.utility.UtilityModuleInterface;
import dev.sheldan.abstracto.core.service.management.FeatureFlagManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -33,7 +33,7 @@ public class Enable implements Command {
List<Parameter> parameters = Arrays.asList(featureName);
return CommandConfiguration.builder()
.name("enable")
.module(UtilityModule.UTILITY)
.module(UtilityModuleInterface.UTILITY)
.parameters(parameters)
.description("Enables features for this server.")
.causesReaction(true)

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.core.commands.channels;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.service.ChannelGroupService;
import net.dv8tion.jda.api.entities.TextChannel;

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.core.commands.channels;
import dev.sheldan.abstracto.command.Module;
import dev.sheldan.abstracto.command.module.ModuleInfo;
import dev.sheldan.abstracto.core.command.ModuleInterface;
import dev.sheldan.abstracto.core.command.module.ModuleInfo;
import org.springframework.stereotype.Component;
@Component
public class ChannelsModule implements Module {
public class ChannelsModuleInterface implements ModuleInterface {
@Override
public ModuleInfo getInfo() {
return ModuleInfo.builder().name("channels").description("Includes utilities to configure the channel configuration stored in the database").build();

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.core.commands.channels;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.service.ChannelGroupService;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.core.commands.channels;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.models.command.PostTargetErrorModel;
import dev.sheldan.abstracto.core.service.PostTargetService;

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.core.commands.channels;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.service.ChannelGroupService;
import net.dv8tion.jda.api.entities.TextChannel;

View File

@@ -1,9 +1,9 @@
package dev.sheldan.abstracto.core.commands.help;
import dev.sheldan.abstracto.command.*;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.command.module.ModuleInfo;
import dev.sheldan.abstracto.command.service.ModuleRegistry;
import dev.sheldan.abstracto.core.command.*;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.command.module.ModuleInfo;
import dev.sheldan.abstracto.core.command.service.ModuleRegistry;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.templating.TemplateService;
import org.apache.commons.lang3.StringUtils;
@@ -104,7 +104,7 @@ public class Help implements Command {
if(depth > 0){
intentation = StringUtils.repeat("-", depth) + ">";
}
ModuleInfo info = module.getModule().getInfo();
ModuleInfo info = module.getModuleInterface().getInfo();
sb.append(String.format(intentation +"**%s** \n", info.getName()));
sb.append(String.format(intentation + "%s \n", info.getDescription()));
if(recursive) {

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.core.commands.help;
import dev.sheldan.abstracto.command.Module;
import dev.sheldan.abstracto.command.module.ModuleInfo;
import dev.sheldan.abstracto.core.command.ModuleInterface;
import dev.sheldan.abstracto.core.command.module.ModuleInfo;
import org.springframework.stereotype.Component;
@Component
public class SupportModule implements Module {
public class SupportModuleInterface implements ModuleInterface {
@Override

View File

@@ -1,12 +1,12 @@
package dev.sheldan.abstracto.core.commands.utility;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.CommandCondition;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.CommandCondition;
import dev.sheldan.abstracto.core.command.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.models.command.EchoModel;
import dev.sheldan.abstracto.templating.TemplateService;

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.core.commands.utility;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.CommandCondition;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.CommandCondition;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.models.command.PingModel;
import dev.sheldan.abstracto.templating.TemplateService;

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.core.commands.utility;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.Parameter;
import dev.sheldan.abstracto.config.AbstractoFeatures;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
@@ -46,7 +46,7 @@ public class SetEmote implements Command {
List<Parameter> parameters = Arrays.asList(emoteKey, emote);
return CommandConfiguration.builder()
.name("setEmote")
.module(UtilityModule.UTILITY)
.module(UtilityModuleInterface.UTILITY)
.parameters(parameters)
.description("Configures the emote key pointing towards a defined emote")
.causesReaction(true)

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.core.commands.utility;
import dev.sheldan.abstracto.command.Module;
import dev.sheldan.abstracto.command.module.ModuleInfo;
import dev.sheldan.abstracto.core.command.ModuleInterface;
import dev.sheldan.abstracto.core.command.module.ModuleInfo;
import org.springframework.stereotype.Component;
@Component
public class UtilityModule implements Module {
public class UtilityModuleInterface implements ModuleInterface {
public static final String UTILITY = "utility";