refactored help command

This commit is contained in:
Sheldan
2020-04-28 15:39:47 +02:00
parent 8e7bc7d98f
commit 93f587bf26
14 changed files with 224 additions and 215 deletions

View File

@@ -5,7 +5,7 @@ import dev.sheldan.abstracto.core.command.config.ModuleInterface;
public class ExperienceModule implements ModuleInterface {
public static final String EXPERIENCE = "utility";
public static final String EXPERIENCE = "experience";
@Override
public ModuleInfo getInfo() {

View File

@@ -100,6 +100,16 @@ public class CommandManager implements CommandRegistry {
return message.getContentRaw().startsWith(configService.getStringValue("prefix", message.getGuild().getIdLong(), defaultPrefix));
}
@Override
public boolean commandExists(String name) {
return commands.stream().anyMatch(command -> command.getConfiguration().getName().equalsIgnoreCase(name));
}
@Override
public Command getCommandByName(String name) {
return commands.stream().filter(command -> command.getConfiguration().getName().equalsIgnoreCase(name)).findFirst().orElse(null);
}
@Override
public String getCommandName(String input, Long serverId) {
return input.replaceFirst(configService.getStringValue("prefix", serverId, defaultPrefix), "");

View File

@@ -1,9 +1,8 @@
package dev.sheldan.abstracto.core.command.service;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.config.CommandHierarchy;
import dev.sheldan.abstracto.core.command.config.ModuleInterface;
import dev.sheldan.abstracto.core.command.config.PackedModule;
import dev.sheldan.abstracto.core.command.config.SingleLevelPackedModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -19,71 +18,39 @@ public class ModuleManager implements ModuleRegistry {
@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;
}
@Override
public SingleLevelPackedModule getPackedModule(ModuleInterface moduleInterface) {
List<Command> commands = commandRegistry.getAllCommandsFromModule(moduleInterface);
return SingleLevelPackedModule
.builder()
.commands(commands)
.moduleInterface(moduleInterface)
.build();
}
@Override
public boolean moduleExists(String name) {
return moduleInterfaces.stream().anyMatch(moduleInterface -> moduleInterface.getInfo().getName().equalsIgnoreCase(name));
}
@Override
public ModuleInterface getModuleByName(String name) {
return moduleInterfaces.stream().filter(moduleInterface -> moduleInterface.getInfo().getName().equalsIgnoreCase(name)).findFirst().orElse(null);
}
@Override
public List<ModuleInterface> getSubModules(ModuleInterface parentModuleInterface) {
return moduleInterfaces.stream().filter(moduleInterface -> moduleInterface.getParentModule() != null && moduleInterface.getParentModule().equals(parentModuleInterface.getInfo().getName())).collect(Collectors.toList());
}
@Override
public ModuleInterface getDefaultModule() {
return getModuleByName("default");
}
}

View File

@@ -3,15 +3,21 @@ package dev.sheldan.abstracto.core.commands.help;
import dev.sheldan.abstracto.core.command.*;
import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.execution.*;
import dev.sheldan.abstracto.core.command.service.CommandRegistry;
import dev.sheldan.abstracto.core.command.service.ModuleRegistry;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.features.CoreFeatures;
import dev.sheldan.abstracto.core.models.template.commands.help.HelpCommandDetailsModel;
import dev.sheldan.abstracto.core.models.template.commands.help.HelpModuleDetailsModel;
import dev.sheldan.abstracto.core.models.template.commands.help.HelpModuleOverviewModel;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
@@ -19,104 +25,49 @@ public class Help implements Command {
@Autowired
private ModuleRegistry registry;
private ModuleRegistry moduleService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private CommandRegistry commandRegistry;
@Override
public CommandResult execute(CommandContext commandContext) {
CommandHierarchy commandStructure = registry.getDetailedModules();
StringBuilder sb = new StringBuilder();
if(commandContext.getParameters().getParameters().isEmpty()){
sb.append("Help | Module overview \n");
sb.append("```");
commandStructure.getRootModules().forEach(packedModule -> {
sb.append(getModule(packedModule, 0, true));
sb.append("\n");
});
sb.append("```");
List<Object> parameters = commandContext.getParameters().getParameters();
if(parameters.isEmpty()) {
ModuleInterface moduleInterface = moduleService.getDefaultModule();
List<ModuleInterface> subModules = moduleService.getSubModules(moduleInterface);
HelpModuleOverviewModel model = (HelpModuleOverviewModel) ContextConverter.fromCommandContext(commandContext, HelpModuleOverviewModel.class);
model.setModules(subModules);
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_module_overview_response", model);
channelService.sendMessageToEndInTextChannel(messageToSend, commandContext.getChannel());
} else {
String parameterValue = commandContext.getParameters().getParameters().get(0).toString();
PackedModule module = commandStructure.getModuleWithName(parameterValue);
if(module != null){
sb.append("Help | Module overview \n");
sb.append(getModule(module, 0, false));
module.getCommands().forEach(command ->
sb.append(getCommand(command))
);
} else {
Command command = commandStructure.getCommandWithName(parameterValue);
if(command != null) {
sb.append("Help | Command overview");
sb.append("\n");
sb.append(getCommand(command));
}
String parameter = (String) parameters.get(0);
if(moduleService.moduleExists(parameter)){
ModuleInterface moduleInterface = moduleService.getModuleByName(parameter);
SingleLevelPackedModule module = moduleService.getPackedModule(moduleInterface);
List<ModuleInterface> subModules = moduleService.getSubModules(moduleInterface);
HelpModuleDetailsModel model = (HelpModuleDetailsModel) ContextConverter.fromCommandContext(commandContext, HelpModuleDetailsModel.class);
model.setModule(module);
model.setSubModules(subModules);
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_module_details_response", model);
channelService.sendMessageToEndInTextChannel(messageToSend, commandContext.getChannel());
} else if(commandRegistry.commandExists(parameter)) {
Command command = commandRegistry.getCommandByName(parameter);
HelpCommandDetailsModel model = (HelpCommandDetailsModel) ContextConverter.fromCommandContext(commandContext, HelpCommandDetailsModel.class);
model.setCommand(command.getConfiguration());
MessageToSend messageToSend = templateService.renderEmbedTemplate("help_command_details_response", model);
channelService.sendMessageToEndInTextChannel(messageToSend, commandContext.getChannel());
}
}
commandContext.getChannel().sendMessage(sb.toString()).queue();
return CommandResult.fromSuccess();
}
private String getCommand(Command command){
StringBuilder sb = new StringBuilder();
CommandConfiguration commandConfiguration = command.getConfiguration();
sb.append(String.format("Command: **%s**", commandConfiguration.getName()));
sb.append("\n");
String descriptionTemplate = getDescriptionTemplate(commandConfiguration.getName());
sb.append(String.format("Description: %s", getTemplateOrDefault(commandConfiguration, descriptionTemplate, commandConfiguration.getDescription())));
sb.append("\n");
HelpInfo helpObj = commandConfiguration.getHelp();
if(helpObj != null){
String usageTemplate = getUsageTemplate(commandConfiguration.getName());
sb.append(String.format("Usage: %s", getTemplateOrDefault(commandConfiguration, usageTemplate, helpObj.getUsage())));
sb.append("\n");
String longHelpTemplate = getLongHelpTemplate(commandConfiguration.getName());
sb.append(String.format("Detailed help: %s", getTemplateOrDefault(commandConfiguration, longHelpTemplate, helpObj.getLongHelp())));
sb.append("\n");
}
return sb.toString();
}
private String getDescriptionTemplate(String commandName) {
return commandName + "_description";
}
private String getUsageTemplate(String commandName) {
return commandName + "_usage";
}
private String getLongHelpTemplate(String commandName) {
return commandName + "_long_help";
}
private String getTemplateOrDefault(CommandConfiguration commandConfiguration, String templateKey, String defaultText) {
if(templateKey == null || !commandConfiguration.isTemplated()) {
return defaultText;
} else {
return templateService.renderTemplateWithMap(templateKey, null);
}
}
private String getModule(PackedModule module, int depth, boolean recursive){
StringBuilder sb = new StringBuilder();
String intentation = "";
if(depth > 0){
intentation = StringUtils.repeat("-", depth) + ">";
}
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) {
module.getSubModules().forEach(subModule ->
sb.append(getModule(subModule, depth + 1, true))
);
}
sb.append("\n");
return sb.toString();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter moduleOrCommandName = Parameter.builder()

View File

@@ -0,0 +1,34 @@
{
"title": {
"title": "Help - Command ${command.name} details"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"description": "Name: **${command.name}**
Description: <#if command.templated >
<#include "${command.name}_description">
<#else>
${command.description}
</#if>
<#if command.help??>
<#if command.help.templated>
Usage: `<#include "${command.name}_usage">`
Detailed help: <#include "${command.name}_long_help">
<#else>
Usage: `${command.help.usage}`
Detailed help: ${command.help.longHelp}
</#if>
</#if>
Parameters:
<#list command.parameters as parameter>
${parameter.name}: ${(parameter.description)!""}
Optional: ${parameter.optional?string('yes', 'no')}
<#else>
No parameters
</#list>
"
}

View File

@@ -0,0 +1,20 @@
{
"title": {
"title": "Help - Module ${module.moduleInterface.info.name} details"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"description": "
Module name: **${module.moduleInterface.info.name}**
Description: ${module.moduleInterface.info.description}
Commands:
<#list module.commands as command>`${command.configuration.name}`<#sep>, </#list>
Submodules: <#list module.subModules as module>`${module.info.name}`<#sep>, </#list>
",
"footer": {
"text": "Use 'help <command name>' for a detailed overview of this command."
}
}

View File

@@ -0,0 +1,19 @@
{
"title": {
"title": "Help - Module overview"
},
"color" : {
"r": 200,
"g": 0,
"b": 255
},
"description": "
<#list modules as module>
Module name: **${module.info.name}**
Description: ${module.info.description}
</#list>
",
"footer": {
"text": "Use 'help <module name>' for a list of commands of this module."
}
}

View File

@@ -1,61 +0,0 @@
package dev.sheldan.abstracto.core.command.config;
import dev.sheldan.abstracto.core.command.Command;
import lombok.Builder;
import lombok.Getter;
import java.util.List;
@Getter @Builder
public class CommandHierarchy {
private List<PackedModule> rootModules;
public PackedModule getModuleWithName(String name){
for (PackedModule module: rootModules) {
PackedModule found = getModuleWithName(name, module);
if(found != null){
return found;
}
}
return null;
}
private PackedModule getModuleWithName(String name, PackedModule module){
if(module.getModuleInterface().getInfo().getName().equals(name)){
return module;
} else {
for (PackedModule subModule: module.getSubModules()) {
PackedModule possibleModule = getModuleWithName(name, subModule);
if(possibleModule != null){
return possibleModule;
}
}
return null;
}
}
public Command getCommandWithName(String name) {
for (PackedModule module: rootModules) {
Command command = getCommandFromModule(name, module);
if(command != null){
return command;
}
}
return null;
}
private Command getCommandFromModule(String name, PackedModule module){
Command foundCommand = module.getCommands().stream().filter(command -> command.getConfiguration().getName().equals(name)).findAny().orElse(null);
if(foundCommand == null){
for (PackedModule subModule: module.getSubModules()) {
Command command = getCommandFromModule(name, subModule);
if(command != null){
return command;
}
}
return null;
} else {
return foundCommand;
}
}
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.command.config;
import dev.sheldan.abstracto.core.command.Command;
import lombok.Builder;
import lombok.Getter;
import java.util.List;
@Builder
@Getter
public class SingleLevelPackedModule {
private ModuleInterface moduleInterface;
private List<Command> commands;
}

View File

@@ -14,5 +14,7 @@ public interface CommandRegistry {
List<Command> getAllCommands();
List<Command> getAllCommandsFromModule(ModuleInterface module);
boolean isCommand(Message message);
boolean commandExists(String name);
Command getCommandByName(String name);
String getCommandName(String input, Long serverId);
}

View File

@@ -1,12 +1,16 @@
package dev.sheldan.abstracto.core.command.service;
import dev.sheldan.abstracto.core.command.config.CommandHierarchy;
import dev.sheldan.abstracto.core.command.config.ModuleInterface;
import dev.sheldan.abstracto.core.command.config.SingleLevelPackedModule;
import java.util.List;
public interface ModuleRegistry {
CommandHierarchy getDetailedModules();
List<ModuleInterface> getModuleInterfaces();
SingleLevelPackedModule getPackedModule(ModuleInterface moduleInterface);
boolean moduleExists(String name);
ModuleInterface getModuleByName(String name);
List<ModuleInterface> getSubModules(ModuleInterface moduleInterface);
ModuleInterface getDefaultModule();
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.models.template.commands.help;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
@Getter
@Setter
@SuperBuilder
public class HelpCommandDetailsModel extends UserInitiatedServerContext {
private CommandConfiguration command;
}

View File

@@ -0,0 +1,18 @@
package dev.sheldan.abstracto.core.models.template.commands.help;
import dev.sheldan.abstracto.core.command.config.ModuleInterface;
import dev.sheldan.abstracto.core.command.config.SingleLevelPackedModule;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Getter
@Setter
@SuperBuilder
public class HelpModuleDetailsModel extends UserInitiatedServerContext {
private SingleLevelPackedModule module;
private List<ModuleInterface> subModules;
}

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.core.models.template.commands.help;
import dev.sheldan.abstracto.core.command.config.ModuleInterface;
import dev.sheldan.abstracto.core.command.config.SingleLevelPackedModule;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Getter
@Setter
@SuperBuilder
public class HelpModuleOverviewModel extends UserInitiatedServerContext {
private List<ModuleInterface> modules;
}