mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-20 23:08:02 +00:00
refactored help command
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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), "");
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
"
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user