mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-07-01 03:22:40 +00:00
Compare commits
32 Commits
release-20
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3080932c48 | ||
|
|
26976e79a6 | ||
|
|
91df290758 | ||
|
|
10bae80377 | ||
|
|
7ba34a97e3 | ||
|
|
cdd2e15969 | ||
|
|
8de0a578db | ||
|
|
072c192e4f | ||
|
|
be5cb132ea | ||
|
|
6deb5aad77 | ||
|
|
32e0c1dc83 | ||
|
|
f0a5fbd059 | ||
|
|
8024eb56b0 | ||
|
|
87937f48b7 | ||
|
|
6dda4132f6 | ||
|
|
67fdfe3b54 | ||
|
|
0586ade8d8 | ||
|
|
ae91c8ee4d | ||
|
|
0cec5284b4 | ||
|
|
51e0da06ae | ||
|
|
f4b048d18b | ||
|
|
6addd5939b | ||
|
|
dafde2d8f6 | ||
|
|
96cbe2db87 | ||
|
|
2ae2542c71 | ||
|
|
a69d4c25ff | ||
|
|
fba5adf573 | ||
|
|
dd21390a60 | ||
|
|
790cca7278 | ||
|
|
52f6fd148e | ||
|
|
708703fc1f | ||
|
|
c5f47cf6e5 |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
|||||||
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
||||||
VERSION=1.6.22
|
VERSION=1.6.29
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>anti-raid</artifactId>
|
<artifactId>anti-raid</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>anti-raid</artifactId>
|
<artifactId>anti-raid</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>assignable-roles</artifactId>
|
<artifactId>assignable-roles</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>assignable-roles</artifactId>
|
<artifactId>assignable-roles</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>assignable-roles-int</artifactId>
|
<artifactId>assignable-roles-int</artifactId>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>custom-command</artifactId>
|
<artifactId>custom-command</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>custom-command</artifactId>
|
<artifactId>custom-command</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>dynamic-activity</artifactId>
|
<artifactId>dynamic-activity</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>dynamic-activity</artifactId>
|
<artifactId>dynamic-activity</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>entertainment</artifactId>
|
<artifactId>entertainment</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>entertainment</artifactId>
|
<artifactId>entertainment</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>experience-tracking</artifactId>
|
<artifactId>experience-tracking</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>experience-tracking</artifactId>
|
<artifactId>experience-tracking</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>giveaway</artifactId>
|
<artifactId>giveaway</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>giveaway-impl</artifactId>
|
<artifactId>giveaway-impl</artifactId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>giveaway</artifactId>
|
<artifactId>giveaway</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>giveaway-int</artifactId>
|
<artifactId>giveaway-int</artifactId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>giveaway</artifactId>
|
<artifactId>giveaway</artifactId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>image-generation</artifactId>
|
<artifactId>image-generation</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>image-generation-impl</artifactId>
|
<artifactId>image-generation-impl</artifactId>
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
package dev.sheldan.abstracto.imagegeneration.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.Parameter;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
|
||||||
|
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.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
|
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.FileService;
|
||||||
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.abstracto.imagegeneration.config.ImageGenerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.imagegeneration.config.ImageGenerationSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.imagegeneration.service.ImageGenerationService;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Grrr extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ImageGenerationService imageGenerationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TemplateService templateService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FileService fileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
private static final String GRRR_EMBED_TEMPLATE_KEY = "grrr_response";
|
||||||
|
public static final String TEXT_PARAMETER_KEY = "text";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||||
|
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||||
|
String text = (String) parameters.get(0);
|
||||||
|
File grrrFile = imageGenerationService.getGrrrImage(text);
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(GRRR_EMBED_TEMPLATE_KEY, new Object(), commandContext.getGuild().getIdLong());
|
||||||
|
// template support does not support binary files
|
||||||
|
AttachedFile file = AttachedFile
|
||||||
|
.builder()
|
||||||
|
.file(grrrFile)
|
||||||
|
.fileName("grrr.png")
|
||||||
|
.build();
|
||||||
|
messageToSend.getAttachedFiles().add(file);
|
||||||
|
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||||
|
.thenAccept(unused -> fileService.safeDeleteIgnoreException(messageToSend.getAttachedFiles().get(0).getFile()))
|
||||||
|
.thenApply(unused -> CommandResult.fromIgnored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
event.deferReply().queue();
|
||||||
|
String text = slashCommandParameterService.getCommandOption(TEXT_PARAMETER_KEY, event, String.class);
|
||||||
|
File grrrFile = imageGenerationService.getGrrrImage(text);
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(GRRR_EMBED_TEMPLATE_KEY, new Object(), event.getGuild().getIdLong());
|
||||||
|
// template support does not support binary files
|
||||||
|
AttachedFile file = AttachedFile
|
||||||
|
.builder()
|
||||||
|
.file(grrrFile)
|
||||||
|
.fileName("grrr.png")
|
||||||
|
.build();
|
||||||
|
messageToSend.getAttachedFiles().add(file);
|
||||||
|
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(messageToSend, event.getHook()))
|
||||||
|
.thenAccept(unused -> fileService.safeDeleteIgnoreException(messageToSend.getAttachedFiles().get(0).getFile()))
|
||||||
|
.thenApply(unused -> CommandResult.fromIgnored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
List<Parameter> parameters = new ArrayList<>();
|
||||||
|
Parameter textParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(TEXT_PARAMETER_KEY)
|
||||||
|
.type(String.class)
|
||||||
|
.templated(true)
|
||||||
|
.remainder(true)
|
||||||
|
.build();
|
||||||
|
parameters.add(textParameter);
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.userInstallable(true)
|
||||||
|
.userCommandConfig(UserCommandConfig.all())
|
||||||
|
.rootCommandName(ImageGenerationSlashCommandNames.IMAGE_GENERATION)
|
||||||
|
.groupName("memes")
|
||||||
|
.commandName("grrr")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name("grrr")
|
||||||
|
.module(UtilityModuleDefinition.UTILITY)
|
||||||
|
.templated(true)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.async(true)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.parameters(parameters)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ImageGenerationFeatureDefinition.IMAGE_GENERATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,10 @@ public class ImageGenerationServiceBean implements ImageGenerationService {
|
|||||||
@Value("${abstracto.feature.imagegeneration.amongusText.url}")
|
@Value("${abstracto.feature.imagegeneration.amongusText.url}")
|
||||||
private String amongusTextUrl;
|
private String amongusTextUrl;
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${abstracto.feature.imagegeneration.grrr.url}")
|
||||||
|
private String grrrUrl;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HttpService httpService;
|
private HttpService httpService;
|
||||||
|
|
||||||
@@ -68,4 +72,13 @@ public class ImageGenerationServiceBean implements ImageGenerationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getGrrrImage(String text) {
|
||||||
|
try {
|
||||||
|
return httpService.downloadFileToTempFile(grrrUrl.replace("{1}", text));
|
||||||
|
} catch (IOException | RequestException e) {
|
||||||
|
throw new AbstractoRunTimeException(String.format("Failed to download grrr image for text %s with error %s", text, e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,3 +11,5 @@ abstracto.feature.imagegeneration.bonk.url=http://${PRIVATE_REST_API_HOST}:${PRI
|
|||||||
abstracto.feature.imagegeneration.bonk.imagesize=128
|
abstracto.feature.imagegeneration.bonk.imagesize=128
|
||||||
|
|
||||||
abstracto.feature.imagegeneration.amongusText.url=http://${PRIVATE_REST_API_HOST}:${PRIVATE_REST_API_PORT}/memes/amongus/text?text={1}
|
abstracto.feature.imagegeneration.amongusText.url=http://${PRIVATE_REST_API_HOST}:${PRIVATE_REST_API_PORT}/memes/amongus/text?text={1}
|
||||||
|
|
||||||
|
abstracto.feature.imagegeneration.grrr.url=http://${PRIVATE_REST_API_HOST}:${PRIVATE_REST_API_PORT}/memes/grrr/text?text={1}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||||
|
<property name="imageGenerationFeature" value="(SELECT id FROM feature WHERE key = 'imageGeneration')"/>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="grrr-command">
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="grrr"/>
|
||||||
|
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${imageGenerationFeature}"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -5,4 +5,5 @@
|
|||||||
<include file="1.5.15/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.5.15/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.5.19/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.5.19/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.5.22/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.5.22/collection.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="1.6.26/collection.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>image-generation</artifactId>
|
<artifactId>image-generation</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>image-generation-int</artifactId>
|
<artifactId>image-generation-int</artifactId>
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ public interface ImageGenerationService {
|
|||||||
File getPatGif(String imageUrl);
|
File getPatGif(String imageUrl);
|
||||||
File getBonkGif(String imageUrl);
|
File getBonkGif(String imageUrl);
|
||||||
File getAmongusTextImage(String text);
|
File getAmongusTextImage(String text);
|
||||||
|
File getGrrrImage(String text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>image-generation</artifactId>
|
<artifactId>image-generation</artifactId>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>invite-filter</artifactId>
|
<artifactId>invite-filter</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>invite-filter</artifactId>
|
<artifactId>invite-filter</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>moderation-int</artifactId>
|
<artifactId>moderation-int</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>link-embed</artifactId>
|
<artifactId>link-embed</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,11 @@ import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManage
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.CommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.CommandInteraction;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.checkerframework.checker.units.qual.A;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -191,11 +193,20 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
|||||||
.builder()
|
.builder()
|
||||||
.message(embeddedMessage)
|
.message(embeddedMessage)
|
||||||
.build();
|
.build();
|
||||||
|
Optional<GuildChannel> existingChannel =
|
||||||
|
channelService.getGuildChannelFromServerOptional(embeddingMessage.getServerId(), embeddingMessage.getChannelId());
|
||||||
|
// if the channel doesnt exist, we dont need to cleanup
|
||||||
|
if(existingChannel.isPresent()) {
|
||||||
MessageToSend messageToSend =
|
MessageToSend messageToSend =
|
||||||
templateService.renderEmbedTemplate(MESSAGE_EMBED_CLEANUP_REPLACEMENT_TEMPLATE, model, embeddingMessage.getServerId());
|
templateService.renderEmbedTemplate(MESSAGE_EMBED_CLEANUP_REPLACEMENT_TEMPLATE, model, embeddingMessage.getServerId());
|
||||||
return channelService.editMessageInAChannelFuture(messageToSend, embeddingMessage.getServerId(), embeddingMessage.getChannelId(),
|
return channelService.editMessageInAChannelFuture(messageToSend, embeddingMessage.getServerId(), embeddingMessage.getChannelId(),
|
||||||
embeddingMessage.getMessageId());
|
embeddingMessage.getMessageId());
|
||||||
}).toList();
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
return FutureUtils.toSingleFutureGeneric(editList).whenComplete((unused, throwable) -> {
|
return FutureUtils.toSingleFutureGeneric(editList).whenComplete((unused, throwable) -> {
|
||||||
if(throwable != null) {
|
if(throwable != null) {
|
||||||
log.warn("Failed to cleanup embedded messages..", throwable);
|
log.warn("Failed to cleanup embedded messages..", throwable);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>link-embed</artifactId>
|
<artifactId>link-embed</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>logging</artifactId>
|
<artifactId>logging</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>logging</artifactId>
|
<artifactId>logging</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>moderation</artifactId>
|
<artifactId>moderation</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
|||||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.moderation.listener.HoneyPotServiceBean;
|
import dev.sheldan.abstracto.moderation.service.HoneyPotServiceBean;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.HoneyPotBanResponseModel;
|
import dev.sheldan.abstracto.moderation.model.template.command.HoneyPotBanResponseModel;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -98,7 +98,7 @@ public class HoneyPotBan extends AbstractConditionableCommand {
|
|||||||
.toList();
|
.toList();
|
||||||
Role honeyPotRole = guild.getRoleById(honeyPotServiceBean.getHoneyPotRoleId(guild.getIdLong()));
|
Role honeyPotRole = guild.getRoleById(honeyPotServiceBean.getHoneyPotRoleId(guild.getIdLong()));
|
||||||
List<CompletableFuture<Void>> futures = currentMembersWithHoneypotRole.stream().map(member ->
|
List<CompletableFuture<Void>> futures = currentMembersWithHoneypotRole.stream().map(member ->
|
||||||
honeyPotServiceBean.banForHoneyPot(member, honeyPotRole)
|
honeyPotServiceBean.banForHoneyPotRole(member, honeyPotRole)
|
||||||
).toList();
|
).toList();
|
||||||
Integer memberCount = currentMembersWithHoneypotRole.size();
|
Integer memberCount = currentMembersWithHoneypotRole.size();
|
||||||
CompletableFutureList<Void> futureList = new CompletableFutureList<>(futures);
|
CompletableFutureList<Void> futureList = new CompletableFutureList<>(futures);
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
|
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
|
||||||
|
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||||
|
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||||
|
import dev.sheldan.abstracto.core.service.MessageService;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.mode.HoneypotMode;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.HoneyPotServiceBean;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class HoneyPotMessageListener implements AsyncMessageReceivedListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigService configService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HoneyPotServiceBean honeyPotServiceBean;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageService messageService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||||
|
Long honeyPotChannel = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_CHANNEL, model.getServerId());
|
||||||
|
if(honeyPotChannel == 0) {
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
if(model.getMessage().getChannelId().equals(honeyPotChannel.toString())) {
|
||||||
|
boolean honeyPotActivated = honeyPotServiceBean.fellIntoHoneyPotIgnoringJoinDate(model.getServerId(), model.getMessage().getMember());
|
||||||
|
if(honeyPotActivated) {
|
||||||
|
log.info("Banning user {} in guild {} due to a message in channel {}.", model.getMessage().getAuthor().getIdLong(), model.getServerId(), honeyPotChannel);
|
||||||
|
honeyPotServiceBean.banForHoneyPotMessage(model.getMessage().getMember(), honeyPotChannel);
|
||||||
|
} else {
|
||||||
|
log.info("NOT banning user {} in guild {} due to a message in honeypot channel {}.", model.getMessage().getAuthor().getIdLong(), model.getServerId(), honeyPotChannel);
|
||||||
|
messageService.deleteMessage(model.getMessage());
|
||||||
|
}
|
||||||
|
return DefaultListenerResult.PROCESSED;
|
||||||
|
}
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.HONEYPOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FeatureMode> getFeatureModeLimitations() {
|
||||||
|
return List.of(HoneypotMode.MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
package dev.sheldan.abstracto.moderation.listener;
|
package dev.sheldan.abstracto.moderation.listener;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.sync.jda.RoleAddedListener;
|
import dev.sheldan.abstracto.core.listener.sync.jda.RoleAddedListener;
|
||||||
import dev.sheldan.abstracto.core.models.listener.RoleAddedModel;
|
import dev.sheldan.abstracto.core.models.listener.RoleAddedModel;
|
||||||
import dev.sheldan.abstracto.core.service.RoleService;
|
import dev.sheldan.abstracto.core.service.RoleService;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.mode.HoneypotMode;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.HoneyPotServiceBean;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -37,7 +40,7 @@ public class HoneyPotRoleAddedListener implements RoleAddedListener {
|
|||||||
boolean fellIntoHoneyPot = honeyPotServiceBean.fellIntoHoneyPot(model.getServerId(), model.getTargetMember());
|
boolean fellIntoHoneyPot = honeyPotServiceBean.fellIntoHoneyPot(model.getServerId(), model.getTargetMember());
|
||||||
if (fellIntoHoneyPot) {
|
if (fellIntoHoneyPot) {
|
||||||
log.info("Banning user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId());
|
log.info("Banning user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId());
|
||||||
honeyPotServiceBean.banForHoneyPot(model.getTargetMember(), model.getRole());
|
honeyPotServiceBean.banForHoneyPotRole(model.getTargetMember(), model.getRole());
|
||||||
} else {
|
} else {
|
||||||
log.info("User {} in server {} will not get banned by honeypot. All existing roles besides {} will be removed.",
|
log.info("User {} in server {} will not get banned by honeypot. All existing roles besides {} will be removed.",
|
||||||
model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), honeyPotRoleId);
|
model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), honeyPotRoleId);
|
||||||
@@ -83,4 +86,8 @@ public class HoneyPotRoleAddedListener implements RoleAddedListener {
|
|||||||
return ListenerPriority.MEDIUM;
|
return ListenerPriority.MEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FeatureMode> getFeatureModeLimitations() {
|
||||||
|
return List.of(HoneypotMode.ROLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package dev.sheldan.abstracto.moderation.listener;
|
package dev.sheldan.abstracto.moderation.service;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
@@ -13,7 +13,6 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
|
|||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||||
import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel;
|
import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel;
|
||||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@@ -68,11 +67,33 @@ public class HoneyPotServiceBean {
|
|||||||
return !allowed;
|
return !allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean fellIntoHoneyPotIgnoringJoinDate(Long serverId, Member member) {
|
||||||
|
Integer levelToSkipBan = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_LEVEL, serverId).intValue();
|
||||||
|
boolean allowed = userHasLevel(member, levelToSkipBan);
|
||||||
|
return !allowed;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Member> getCurrentMembersWithHoneypotRole(Guild guild) {
|
public List<Member> getCurrentMembersWithHoneypotRole(Guild guild) {
|
||||||
return memberService.getMembersWithRole(guild.getIdLong(), getHoneyPotRoleId(guild.getIdLong()));
|
return memberService.getMembersWithRole(guild.getIdLong(), getHoneyPotRoleId(guild.getIdLong()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> banForHoneyPot(Member targetMember, Role role) {
|
public CompletableFuture<Void> banForHoneyPotMessage(Member targetMember, Long channelId) {
|
||||||
|
HoneyPotReasonModel reasonModel = HoneyPotReasonModel
|
||||||
|
.builder()
|
||||||
|
.memberDisplay(MemberDisplay.fromMember(targetMember))
|
||||||
|
.build();
|
||||||
|
ServerUser bannedUser = ServerUser.fromMember(targetMember);
|
||||||
|
String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel, bannedUser.getServerId());
|
||||||
|
return banService.banUserWithNotification(bannedUser, banReason, ServerUser.fromMember(targetMember.getGuild().getSelfMember()),
|
||||||
|
targetMember.getGuild(), Duration.ofDays(7)).thenAccept(banResult -> {
|
||||||
|
log.info("Banned user {} in guild {} due to a message in channel {}.", bannedUser.getUserId(), bannedUser.getServerId(), channelId);
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to ban user {} in guild {} due to a message in channel {}.", bannedUser.getUserId(), bannedUser.getServerId(), channelId, throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> banForHoneyPotRole(Member targetMember, Role role) {
|
||||||
HoneyPotReasonModel reasonModel = HoneyPotReasonModel
|
HoneyPotReasonModel reasonModel = HoneyPotReasonModel
|
||||||
.builder()
|
.builder()
|
||||||
.memberDisplay(MemberDisplay.fromMember(targetMember))
|
.memberDisplay(MemberDisplay.fromMember(targetMember))
|
||||||
@@ -91,7 +112,7 @@ public class HoneyPotServiceBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean userHasLevel(Member member, Integer level) {
|
private boolean userHasLevel(Member member, Integer level) {
|
||||||
log.info("Checking if member {} is ignored to click on the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong());
|
log.info("Checking if member {} is ignored by the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong());
|
||||||
Map<String, Object> parameters = new HashMap<>();
|
Map<String, Object> parameters = new HashMap<>();
|
||||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||||
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
|
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
|
||||||
@@ -99,3 +99,14 @@ abstracto.systemConfigs.honeypotIgnoredJoinDurationSeconds.longValue=86400
|
|||||||
|
|
||||||
abstracto.featureFlags.honeypot.featureName=honeypot
|
abstracto.featureFlags.honeypot.featureName=honeypot
|
||||||
abstracto.featureFlags.honeypot.enabled=false
|
abstracto.featureFlags.honeypot.enabled=false
|
||||||
|
|
||||||
|
abstracto.featureModes.honeypotRole.featureName=honeypot
|
||||||
|
abstracto.featureModes.honeypotRole.mode=honeypotRole
|
||||||
|
abstracto.featureModes.honeypotRole.enabled=false
|
||||||
|
|
||||||
|
abstracto.featureModes.honeypotMessage.featureName=honeypot
|
||||||
|
abstracto.featureModes.honeypotMessage.mode=honeypotMessage
|
||||||
|
abstracto.featureModes.honeypotMessage.enabled=false
|
||||||
|
|
||||||
|
abstracto.systemConfigs.honeypotChannel.name=honeypotChannel
|
||||||
|
abstracto.systemConfigs.honeypotChannel.longValue=0
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>moderation</artifactId>
|
<artifactId>moderation</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.moderation.config.feature;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.mode.HoneypotMode;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -12,6 +14,7 @@ public class HoneyPotFeatureConfig implements FeatureConfig {
|
|||||||
|
|
||||||
public static final String HONEYPOT_ROLE_ID = "honeypotRoleId";
|
public static final String HONEYPOT_ROLE_ID = "honeypotRoleId";
|
||||||
public static final String HONEYPOT_IGNORED_LEVEL = "honeypotIgnoredLevel";
|
public static final String HONEYPOT_IGNORED_LEVEL = "honeypotIgnoredLevel";
|
||||||
|
public static final String HONEYPOT_CHANNEL = "honeypotChannel";
|
||||||
public static final String HONEYPOT_IGNORED_JOIN_DURATION_SECONDS = "honeypotIgnoredJoinDurationSeconds";
|
public static final String HONEYPOT_IGNORED_JOIN_DURATION_SECONDS = "honeypotIgnoredJoinDurationSeconds";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -21,6 +24,11 @@ public class HoneyPotFeatureConfig implements FeatureConfig {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRequiredSystemConfigKeys() {
|
public List<String> getRequiredSystemConfigKeys() {
|
||||||
return Arrays.asList(HONEYPOT_ROLE_ID, HONEYPOT_IGNORED_LEVEL, HONEYPOT_IGNORED_JOIN_DURATION_SECONDS);
|
return Arrays.asList(HONEYPOT_ROLE_ID, HONEYPOT_IGNORED_LEVEL, HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, HONEYPOT_CHANNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FeatureMode> getAvailableModes() {
|
||||||
|
return Arrays.asList(HoneypotMode.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.config.feature.mode;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum HoneypotMode implements FeatureMode {
|
||||||
|
ROLE("honeypotRole"),
|
||||||
|
MESSAGE("honeypotMessage");
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
HoneypotMode(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>modmail</artifactId>
|
<artifactId>modmail</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class AnonReply extends AbstractConditionableCommand {
|
|||||||
}
|
}
|
||||||
Long threadId = modMailThread.getId();
|
Long threadId = modMailThread.getId();
|
||||||
return userService.retrieveUserForId(modMailThread.getUser().getUserReference().getId()).thenCompose(user ->
|
return userService.retrieveUserForId(modMailThread.getUser().getUserReference().getId()).thenCompose(user ->
|
||||||
modMailThreadService.loadExecutingMemberAndRelay(threadId, text, commandContext.getMessage(), true, user, commandContext.getGuild())
|
modMailThreadService.relayMessageToDm(threadId, text, commandContext.getMessage(), true, user, commandContext.getGuild(), commandContext.getAuthor())
|
||||||
).thenApply(aVoid -> CommandResult.fromSuccess());
|
).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.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.Parameter;
|
||||||
|
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.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.UserService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.modmail.exception.ModMailThreadClosedException;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.ModMailThread;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.ModMailThreadState;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.QuickReplyService;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.management.QuickReplyManagementService;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class QuickReplyCommand extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
private static final String QUICK_REPLY_COMMAND = "quickReply";
|
||||||
|
private static final String QUICK_REPLY_NAME_PARAMETER = "name";
|
||||||
|
private static final String QUICK_REPLY_ANONYMOUS_PARAMETER = "anonymous";
|
||||||
|
private static final String QUICK_REPLY_RESPONSE_TEMPLATE_KEY = "quickReply_response";
|
||||||
|
private static final String QUICK_REPLY_NO_QUICK_REPLY_FOUND_TEMPLATE_KEY = "quickReply_no_quick_reply_response";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyService quickReplyService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyManagementService quickReplyManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ModMailThreadService modMailThreadService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ModMailThreadManagementService modMailThreadManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
String name = slashCommandParameterService.getCommandOption(QUICK_REPLY_NAME_PARAMETER, event, String.class);
|
||||||
|
Optional<QuickReply> quickReplyOptional = quickReplyService.getQuickReply(name, event.getGuild());
|
||||||
|
if(quickReplyOptional.isEmpty()) {
|
||||||
|
return interactionService.replyEmbed(QUICK_REPLY_NO_QUICK_REPLY_FOUND_TEMPLATE_KEY, event)
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
ModMailThread modMailThread = modMailThreadManagementService.getByChannelId(event.getChannel().getIdLong());
|
||||||
|
if(ModMailThreadState.CLOSED.equals(modMailThread.getState()) || ModMailThreadState.CLOSING.equals(modMailThread.getState())) {
|
||||||
|
throw new ModMailThreadClosedException();
|
||||||
|
}
|
||||||
|
Long threadId = modMailThread.getId();
|
||||||
|
QuickReply quickReply = quickReplyOptional.get();
|
||||||
|
Boolean anonymousOverride = null;
|
||||||
|
if(slashCommandParameterService.hasCommandOption(QUICK_REPLY_ANONYMOUS_PARAMETER, event)) {
|
||||||
|
anonymousOverride = slashCommandParameterService.getCommandOption(QUICK_REPLY_ANONYMOUS_PARAMETER, event, Boolean.class);
|
||||||
|
}
|
||||||
|
boolean anonymous;
|
||||||
|
if(anonymousOverride != null) {
|
||||||
|
anonymous = anonymousOverride;
|
||||||
|
} else {
|
||||||
|
anonymous = quickReply.getAnonymous();
|
||||||
|
}
|
||||||
|
Long snowFlake = SnowflakeUtils.createSnowFlake();
|
||||||
|
Long targetUserId = modMailThread.getUser().getUserReference().getId();
|
||||||
|
event.deferReply(true).queue();
|
||||||
|
return
|
||||||
|
userService.retrieveUserForId(targetUserId).thenCompose(user ->
|
||||||
|
modMailThreadService.relayMessageToDm(threadId, quickReply.getAdditionalMessage(), snowFlake, anonymous, user,
|
||||||
|
event.getGuild(), event.getMember())
|
||||||
|
).thenCompose(unused -> FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(QUICK_REPLY_RESPONSE_TEMPLATE_KEY, new Object(), event.getHook())))
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
|
||||||
|
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), QUICK_REPLY_NAME_PARAMETER)) {
|
||||||
|
String input = event.getFocusedOption().getValue();
|
||||||
|
AServer server = serverManagementService.loadServer(event.getGuild());
|
||||||
|
return quickReplyManagementService.getQuickRepliesContaining(input, server)
|
||||||
|
.stream().map(quickReply -> quickReply.getName().toLowerCase())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModMailFeatureDefinition.MOD_MAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Parameter replyContentParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_NAME_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.supportsAutoComplete(true)
|
||||||
|
.type(String.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Parameter replyAnonymousparameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_ANONYMOUS_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.optional(true)
|
||||||
|
.type(Boolean.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Parameter> parameters = Arrays.asList(replyContentParameter, replyAnonymousparameter);
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.rootCommandName(ModMailSlashCommandNames.MODMAIL)
|
||||||
|
.commandName("quickReply")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(QUICK_REPLY_COMMAND)
|
||||||
|
.module(UtilityModuleDefinition.UTILITY)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.slashCommandOnly(true)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.causesReaction(true)
|
||||||
|
.parameters(parameters)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.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.Parameter;
|
||||||
|
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.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.QuickReplyService;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class QuickReplyCreate extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
private static final String CREATE_QUICK_REPLY_COMMAND = "createQuickReply";
|
||||||
|
private static final String QUICK_REPLY_NAME_PARAMETER = "name";
|
||||||
|
private static final String QUICK_REPLY_CONTENT_PARAMETER = "response";
|
||||||
|
private static final String QUICK_REPLY_ANONYMOUS_PARAMETER = "anonymous";
|
||||||
|
private static final String CREATE_QUICK_REPLY_RESPONSE_TEMPLATE_KEY = "createQuickReply_response";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyService quickReplyService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
String name = slashCommandParameterService.getCommandOption(QUICK_REPLY_NAME_PARAMETER, event, String.class);
|
||||||
|
String content = slashCommandParameterService.getCommandOption(QUICK_REPLY_CONTENT_PARAMETER, event, String.class);
|
||||||
|
boolean anonymous;
|
||||||
|
if(slashCommandParameterService.hasCommandOption(QUICK_REPLY_ANONYMOUS_PARAMETER, event)) {
|
||||||
|
anonymous = slashCommandParameterService.getCommandOption(QUICK_REPLY_ANONYMOUS_PARAMETER, event, Boolean.class);
|
||||||
|
} else {
|
||||||
|
anonymous = false;
|
||||||
|
}
|
||||||
|
quickReplyService.createQuickReply(name, content, event.getMember(), anonymous);
|
||||||
|
return interactionService.replyEmbed(CREATE_QUICK_REPLY_RESPONSE_TEMPLATE_KEY, event)
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
Parameter commandNameParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_NAME_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.type(String.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Parameter replyContentParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_CONTENT_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.type(String.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Parameter replyAnonymousparameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_ANONYMOUS_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.optional(true)
|
||||||
|
.type(Boolean.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Parameter> parameters = Arrays.asList(commandNameParameter, replyContentParameter, replyAnonymousparameter);
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||||
|
.rootCommandName(ModMailSlashCommandNames.MODMAIL)
|
||||||
|
.commandName("createQuickReply")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(CREATE_QUICK_REPLY_COMMAND)
|
||||||
|
.module(UtilityModuleDefinition.UTILITY)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.slashCommandOnly(true)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.causesReaction(true)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.parameters(parameters)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModMailFeatureDefinition.MOD_MAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.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.Parameter;
|
||||||
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.QuickReplyService;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.management.QuickReplyManagementService;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class QuickReplyDelete extends AbstractConditionableCommand {
|
||||||
|
private static final String DELETE_QUICK_REPLY_COMMAND = "deleteQuickReply";
|
||||||
|
private static final String DELETE_QUICK_REPLY_RESPONSE_TEMPLATE_KEY = "deleteQuickReply_response";
|
||||||
|
private static final String QUICK_REPLY_NAME_PARAMETER = "name";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyService customCommandService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyManagementService quickReplyManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandService slashCommandService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
String name = slashCommandParameterService.getCommandOption(QUICK_REPLY_NAME_PARAMETER, event, String.class);
|
||||||
|
customCommandService.deleteQuickReply(name, event.getGuild());
|
||||||
|
return slashCommandService.completeConfirmableCommand(event, DELETE_QUICK_REPLY_RESPONSE_TEMPLATE_KEY)
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
|
||||||
|
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), QUICK_REPLY_NAME_PARAMETER)) {
|
||||||
|
String input = event.getFocusedOption().getValue();
|
||||||
|
AServer server = serverManagementService.loadServer(event.getGuild());
|
||||||
|
return quickReplyManagementService.getQuickRepliesContaining(input, server)
|
||||||
|
.stream().map(quickReply -> quickReply.getName().toLowerCase())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
Parameter quickReplyNameParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(QUICK_REPLY_NAME_PARAMETER)
|
||||||
|
.templated(true)
|
||||||
|
.supportsAutoComplete(true)
|
||||||
|
.type(String.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<Parameter> parameters = Arrays.asList(quickReplyNameParameter);
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||||
|
.rootCommandName(ModMailSlashCommandNames.MODMAIL)
|
||||||
|
.commandName("deleteQuickReply")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(DELETE_QUICK_REPLY_COMMAND)
|
||||||
|
.module(UtilityModuleDefinition.UTILITY)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.causesReaction(true)
|
||||||
|
.slashCommandOnly(true)
|
||||||
|
.requiresConfirmation(true)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.parameters(parameters)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModMailFeatureDefinition.MOD_MAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.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.execution.CommandResult;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.service.PaginatorService;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.modmail.config.ModMailSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.template.QuickRepliesListResponseModel;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.QuickReplyService;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class QuickReplyList extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
|
||||||
|
private static final String LIST_QUICK_REPLIES_COMMAND = "listQuickReplies";
|
||||||
|
private static final String LIST_QUICK_REPLIES_TEMPLATE_KEY = "listQuickReplies_response";
|
||||||
|
private static final String NO_QUICK_REPLIES_TEMPLATE_KEY = "listQuickReplies_no_quick_replies_response";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyService quickReplyService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PaginatorService paginatorService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
List<QuickReply> quickReplies = quickReplyService.getQuickReplies(event.getGuild());
|
||||||
|
if(quickReplies.isEmpty()) {
|
||||||
|
return interactionService.replyEmbed(NO_QUICK_REPLIES_TEMPLATE_KEY, event)
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
QuickRepliesListResponseModel model = QuickRepliesListResponseModel.fromQuickReplies(quickReplies);
|
||||||
|
return paginatorService.createPaginatorFromTemplate(LIST_QUICK_REPLIES_TEMPLATE_KEY, model, event)
|
||||||
|
.thenApply(unused -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModMailFeatureDefinition.MOD_MAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.rootCommandName(ModMailSlashCommandNames.MODMAIL)
|
||||||
|
.commandName("listQuickReply")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(LIST_QUICK_REPLIES_COMMAND)
|
||||||
|
.module(UtilityModuleDefinition.UTILITY)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.slashCommandOnly(true)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.causesReaction(true)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
|
|||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.service.MemberService;
|
|
||||||
import dev.sheldan.abstracto.core.service.UserService;
|
import dev.sheldan.abstracto.core.service.UserService;
|
||||||
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
|
import dev.sheldan.abstracto.modmail.condition.ModMailContextCondition;
|
||||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
import dev.sheldan.abstracto.modmail.config.ModMailFeatureDefinition;
|
||||||
@@ -52,7 +51,7 @@ public class Reply extends AbstractConditionableCommand {
|
|||||||
}
|
}
|
||||||
Long threadId = modMailThread.getId();
|
Long threadId = modMailThread.getId();
|
||||||
return userService.retrieveUserForId(modMailThread.getUser().getUserReference().getId()).thenCompose(user ->
|
return userService.retrieveUserForId(modMailThread.getUser().getUserReference().getId()).thenCompose(user ->
|
||||||
modMailThreadService.loadExecutingMemberAndRelay(threadId, text, commandContext.getMessage(), false, user, commandContext.getGuild())
|
modMailThreadService.relayMessageToDm(threadId, text, commandContext.getMessage(), false, user, commandContext.getGuild(), commandContext.getAuthor())
|
||||||
).thenApply(aVoid -> CommandResult.fromSuccess());
|
).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import dev.sheldan.abstracto.core.command.service.CommandService;
|
|||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageUpdatedListener;
|
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageUpdatedListener;
|
||||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
|
||||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||||
import dev.sheldan.abstracto.core.models.listener.MessageUpdatedModel;
|
import dev.sheldan.abstracto.core.models.listener.MessageUpdatedModel;
|
||||||
@@ -125,7 +124,6 @@ public class ModMailMessageEditedListener implements AsyncMessageUpdatedListener
|
|||||||
.builder()
|
.builder()
|
||||||
.text(newText)
|
.text(newText)
|
||||||
.modMailThread(modMailMessage.getThreadReference())
|
.modMailThread(modMailMessage.getThreadReference())
|
||||||
.postedMessage(loadedMessage)
|
|
||||||
.attachedImageUrls(imageUrls)
|
.attachedImageUrls(imageUrls)
|
||||||
.remainingAttachments(otherAttachments)
|
.remainingAttachments(otherAttachments)
|
||||||
.anonymous(modMailMessage.getAnonymous())
|
.anonymous(modMailMessage.getAnonymous())
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class ModmailReminderListener implements ModmailThreadActionListener {
|
|||||||
log.debug("Thread {} is closed - ignoring.", model.getThreadId());
|
log.debug("Thread {} is closed - ignoring.", model.getThreadId());
|
||||||
return ModmailThreadActionListenerResult.IGNORED;
|
return ModmailThreadActionListenerResult.IGNORED;
|
||||||
}
|
}
|
||||||
Instant timeStampToConsider = getTimestampToUse(thread);
|
Instant timeStampToConsider = getTimestampToUse(thread, duration);
|
||||||
boolean mustBeReminded = timeInPastDuration.isAfter(timeStampToConsider);
|
boolean mustBeReminded = timeInPastDuration.isAfter(timeStampToConsider);
|
||||||
if (mustBeReminded) {
|
if (mustBeReminded) {
|
||||||
sendReminder(thread)
|
sendReminder(thread)
|
||||||
@@ -97,14 +97,17 @@ public class ModmailReminderListener implements ModmailThreadActionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Instant getTimestampToUse(ModMailThread thread) {
|
private static Instant getTimestampToUse(ModMailThread thread, Duration configuredDuration) {
|
||||||
if (thread.getRemindersSnoozedUntil() != null) {
|
if (thread.getRemindersSnoozedUntil() != null) {
|
||||||
return thread.getRemindersSnoozedUntil();
|
return thread.getRemindersSnoozedUntil().minus(configuredDuration);
|
||||||
}
|
}
|
||||||
return getUpdatedOrCrated(thread);
|
return getUpdatedOrCrated(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Instant getUpdatedOrCrated(ModMailThread thread) {
|
private static Instant getUpdatedOrCrated(ModMailThread thread) {
|
||||||
|
if(thread.getLastUpdated() != null) {
|
||||||
|
return thread.getLastUpdated();
|
||||||
|
}
|
||||||
if(thread.getUpdated() != null) {
|
if(thread.getUpdated() != null) {
|
||||||
return thread.getUpdated();
|
return thread.getUpdated();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.repository;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface QuickReplyRepository extends JpaRepository<QuickReply, Long> {
|
||||||
|
Optional<QuickReply> getByNameIgnoreCaseAndServer(String name, AServer server);
|
||||||
|
void deleteByNameAndServer(String name, AServer server);
|
||||||
|
List<QuickReply> findByServer(AServer server);
|
||||||
|
List<QuickReply> findByNameStartsWithIgnoreCaseAndServer(String prefix, AServer server);
|
||||||
|
List<QuickReply> findByNameContainingIgnoreCaseAndServer(String name, AServer server);
|
||||||
|
}
|
||||||
@@ -50,6 +50,7 @@ import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|||||||
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -748,18 +749,8 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public CompletableFuture<Void> loadExecutingMemberAndRelay(Long modmailThreadId, String text, Message replyCommandMessage, boolean anonymous, User user, Guild guild) {
|
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message replyCommandMessage, boolean anonymous, User user, Guild guild, Member executingMember) {
|
||||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", replyCommandMessage.getId(), user.getId(), modmailThreadId, guild.getId());
|
|
||||||
return memberService.getMemberInServerAsync(replyCommandMessage.getGuild().getIdLong(), replyCommandMessage.getAuthor().getIdLong())
|
|
||||||
.thenCompose(executingMember -> self.relayMessageToDm(modmailThreadId, text, replyCommandMessage, anonymous, user, executingMember));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message replyCommandMessage, boolean anonymous, User user, Member executingMember) {
|
|
||||||
metricService.incrementCounter(MDOMAIL_THREAD_MESSAGE_SENT);
|
|
||||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
|
||||||
List<String> imageUrls = replyCommandMessage
|
List<String> imageUrls = replyCommandMessage
|
||||||
.getAttachments()
|
.getAttachments()
|
||||||
.stream()
|
.stream()
|
||||||
@@ -771,11 +762,19 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(attachment -> !attachment.isImage())
|
.filter(attachment -> !attachment.isImage())
|
||||||
.collect(Collectors.toMap(Message.Attachment::getFileName, Message.Attachment::getUrl));
|
.collect(Collectors.toMap(Message.Attachment::getFileName, Message.Attachment::getUrl));
|
||||||
|
return relayMessageToDMInternal(modmailThreadId, text, replyCommandMessage.getIdLong(), imageUrls, otherAttachments, anonymous, user, guild, executingMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Void> relayMessageToDMInternal(Long modmailThreadId, String text, Long messageId, List<String> imageUrls, Map<String, String> otherAttachments,
|
||||||
|
boolean anonymous, User user, Guild guild, Member executingMember) {
|
||||||
|
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", messageId, user.getId(), modmailThreadId, guild.getId());
|
||||||
|
metricService.incrementCounter(MDOMAIL_THREAD_MESSAGE_SENT);
|
||||||
|
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
||||||
|
|
||||||
ModMailModeratorReplyModel.ModMailModeratorReplyModelBuilder modMailModeratorReplyModelBuilder = ModMailModeratorReplyModel
|
ModMailModeratorReplyModel.ModMailModeratorReplyModelBuilder modMailModeratorReplyModelBuilder = ModMailModeratorReplyModel
|
||||||
.builder()
|
.builder()
|
||||||
.text(text)
|
.text(text)
|
||||||
.modMailThread(modMailThread)
|
.modMailThread(modMailThread)
|
||||||
.postedMessage(replyCommandMessage)
|
|
||||||
.remainingAttachments(otherAttachments)
|
.remainingAttachments(otherAttachments)
|
||||||
.attachedImageUrls(imageUrls)
|
.attachedImageUrls(imageUrls)
|
||||||
.anonymous(anonymous)
|
.anonymous(anonymous)
|
||||||
@@ -796,10 +795,17 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
|||||||
sameThreadMessageFuture = CompletableFuture.completedFuture(null);
|
sameThreadMessageFuture = CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
||||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, future.join(), replyCommandMessage.getMember(), replyCommandMessage.getIdLong(), sameThreadMessageFuture.join())
|
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, future.join(), executingMember, messageId,
|
||||||
|
sameThreadMessageFuture.join())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> relayMessageToDm(Long threadId, String text, Long uniqueMessageId, boolean anonymous, User targetUser, Guild guild,
|
||||||
|
Member executingMember) {
|
||||||
|
return relayMessageToDMInternal(threadId, text, uniqueMessageId, new ArrayList<>(), new HashMap<>(), anonymous, targetUser, guild, executingMember);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> closeModMailThreadEvaluateLogging(ModMailThread modMailThread, ClosingContext closingConfig, List<UndoActionInstance> undoActions) {
|
public CompletableFuture<Void> closeModMailThreadEvaluateLogging(ModMailThread modMailThread, ClosingContext closingConfig, List<UndoActionInstance> undoActions) {
|
||||||
boolean loggingMode = featureModeService.featureModeActive(ModMailFeatureDefinition.MOD_MAIL, modMailThread.getServer(), ModMailMode.LOGGING);
|
boolean loggingMode = featureModeService.featureModeActive(ModMailFeatureDefinition.MOD_MAIL, modMailThread.getServer(), ModMailMode.LOGGING);
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.UserManagementService;
|
||||||
|
import dev.sheldan.abstracto.modmail.exception.QuickReplyExistsException;
|
||||||
|
import dev.sheldan.abstracto.modmail.exception.QuickReplyNotFoundException;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import dev.sheldan.abstracto.modmail.service.management.QuickReplyManagementService;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class QuickReplyServiceBean implements QuickReplyService {
|
||||||
|
@Autowired
|
||||||
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyManagementService quickReplyManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QuickReply createQuickReply(String name, String content, Member creator, boolean anonymous) {
|
||||||
|
if(quickReplyManagementService.getQuickReplyByName(name, creator.getGuild().getIdLong()).isPresent()) {
|
||||||
|
throw new QuickReplyExistsException();
|
||||||
|
}
|
||||||
|
AUserInAServer creatorUser = userInServerManagementService.loadOrCreateUser(creator);
|
||||||
|
return quickReplyManagementService.createQuickReply(name, content, creatorUser, anonymous);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuickReply(String name, Guild guild) {
|
||||||
|
if(quickReplyManagementService.getQuickReplyByName(name, guild.getIdLong()).isEmpty()) {
|
||||||
|
throw new QuickReplyNotFoundException();
|
||||||
|
}
|
||||||
|
AServer server = serverManagementService.loadServer(guild);
|
||||||
|
quickReplyManagementService.deleteQuickReply(name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<QuickReply> getQuickReplies(Guild guild) {
|
||||||
|
AServer server = serverManagementService.loadServer(guild);
|
||||||
|
return quickReplyManagementService.getQuickReplies(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<QuickReply> getQuickReply(String name, Guild guild) {
|
||||||
|
return quickReplyManagementService.getQuickReplyByName(name, guild.getIdLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<QuickReply> getQuickRepliesContaining(String name, Guild guild) {
|
||||||
|
AServer server = serverManagementService.loadServer(guild);
|
||||||
|
return quickReplyManagementService.getQuickRepliesContaining(name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.service.management;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import dev.sheldan.abstracto.modmail.repository.QuickReplyRepository;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class QuickReplyManagementServiceBean implements QuickReplyManagementService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private QuickReplyRepository repository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<QuickReply> getQuickReplyByName(String name, Long serverId) {
|
||||||
|
AServer server = serverManagementService.loadServer(serverId);
|
||||||
|
return repository.getByNameIgnoreCaseAndServer(name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QuickReply createQuickReply(String name, String content, AUserInAServer creator, boolean anonymous) {
|
||||||
|
QuickReply quickReply = QuickReply
|
||||||
|
.builder()
|
||||||
|
.name(name)
|
||||||
|
.additionalMessage(content)
|
||||||
|
.anonymous(anonymous)
|
||||||
|
.server(creator.getServerReference())
|
||||||
|
.creator(creator)
|
||||||
|
.build();
|
||||||
|
return repository.save(quickReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuickReply(String name, AServer server) {
|
||||||
|
repository.deleteByNameAndServer(name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<QuickReply> getQuickReplies(AServer server) {
|
||||||
|
return repository.findByServer(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<QuickReply> getQuickRepliesContaining(String name, AServer server) {
|
||||||
|
return repository.findByNameContainingIgnoreCaseAndServer(name, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<property name="modmailModule" value="(SELECT id FROM module WHERE name = 'modmail')"/>
|
||||||
|
<property name="modmailFeature" value="(SELECT id FROM feature WHERE key = 'modmail')"/>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="quickReply-commands">
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="quickReply"/>
|
||||||
|
<column name="module_id" valueComputed="${modmailModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${modmailFeature}"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="createQuickReply"/>
|
||||||
|
<column name="module_id" valueComputed="${modmailModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${modmailFeature}"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="deleteQuickReply"/>
|
||||||
|
<column name="module_id" valueComputed="${modmailModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${modmailFeature}"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="listQuickReplies"/>
|
||||||
|
<column name="module_id" valueComputed="${modmailModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${modmailFeature}"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<changeSet author="Sheldan" id="quick_reply-table">
|
||||||
|
<createTable tableName="quick_reply">
|
||||||
|
<column name="id" type="BIGINT" autoIncrement="true">
|
||||||
|
<constraints nullable="false" primaryKey="true" primaryKeyName="quick_reply_pkey"/>
|
||||||
|
</column>
|
||||||
|
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="creator_user_in_server_id" type="BIGINT">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="additional_message" type="VARCHAR(2048)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="name" type="VARCHAR(64)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="anonymous" type="BOOLEAN"/>
|
||||||
|
<column name="server_id" type="BIGINT">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||||
|
</createTable>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="quick_reply"
|
||||||
|
constraintName="fk_quick_reply_server" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="creator_user_in_server_id" baseTableName="quick_reply"
|
||||||
|
constraintName="fk_quick_reply_creator" deferrable="false" initiallyDeferred="false"
|
||||||
|
onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||||
|
<sql>
|
||||||
|
DROP TRIGGER IF EXISTS quick_reply_update_trigger ON quick_reply;
|
||||||
|
CREATE TRIGGER quick_reply_update_trigger BEFORE UPDATE ON quick_reply FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||||
|
</sql>
|
||||||
|
<sql>
|
||||||
|
DROP TRIGGER IF EXISTS quick_reply_insert_trigger ON quick_reply;
|
||||||
|
CREATE TRIGGER quick_reply_insert_trigger BEFORE INSERT ON quick_reply FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||||
|
</sql>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||||
|
<include file="quick_reply.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -7,4 +7,5 @@
|
|||||||
<include file="1.5.51/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.5.51/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.6.22/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.6.22/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.6.23/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.6.23/collection.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="1.6.29/collection.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>modmail</artifactId>
|
<artifactId>modmail</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.exception;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||||
|
|
||||||
|
public class QuickReplyExistsException extends AbstractoTemplatableException {
|
||||||
|
@Override
|
||||||
|
public String getTemplateName() {
|
||||||
|
return "quick_reply_exists_exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getTemplateModel() {
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.exception;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||||
|
|
||||||
|
public class QuickReplyNotFoundException extends AbstractoTemplatableException {
|
||||||
|
@Override
|
||||||
|
public String getTemplateName() {
|
||||||
|
return "quick_reply_not_found_exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getTemplateModel() {
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.model.database;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "quick_reply")
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class QuickReply implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "id", nullable = false)
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "additional_message")
|
||||||
|
private String additionalMessage;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "server_id")
|
||||||
|
private AServer server;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "creator_user_in_server_id")
|
||||||
|
private AUserInAServer creator;
|
||||||
|
|
||||||
|
@Column(name = "anonymous")
|
||||||
|
private Boolean anonymous;
|
||||||
|
|
||||||
|
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||||
|
private Instant created;
|
||||||
|
|
||||||
|
@Column(name = "updated", insertable = false, updatable = false)
|
||||||
|
private Instant updated;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -23,15 +22,7 @@ public class ModMailModeratorReplyModel {
|
|||||||
* The staff {@link Member} which replied to the thread, be it anonymously or normal.
|
* The staff {@link Member} which replied to the thread, be it anonymously or normal.
|
||||||
*/
|
*/
|
||||||
private Member moderator;
|
private Member moderator;
|
||||||
/**
|
|
||||||
* The text which was used to reply. This is necessary, because the reply is triggered via a command, so
|
|
||||||
* we would need re-parse the {@link Message} in order to find the value to display
|
|
||||||
*/
|
|
||||||
private String text;
|
private String text;
|
||||||
/**
|
|
||||||
* The {@link Message} which contained the command to reply to the user. This is needed for attachments.
|
|
||||||
*/
|
|
||||||
private Message postedMessage;
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the reply should be shown anonymous
|
* Whether or not the reply should be shown anonymous
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.model.template;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
public class QuickRepliesListResponseModel {
|
||||||
|
private List<QuickReplyListItem> quickReplies;
|
||||||
|
|
||||||
|
public static QuickRepliesListResponseModel fromQuickReplies(List<QuickReply> quickReplies) {
|
||||||
|
return QuickRepliesListResponseModel
|
||||||
|
.builder()
|
||||||
|
.quickReplies(quickReplies
|
||||||
|
.stream()
|
||||||
|
.map(QuickReplyListItem::fromQuickReply)
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.model.template;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class QuickReplyListItem {
|
||||||
|
private String name;
|
||||||
|
private String content;
|
||||||
|
private boolean anonymous;
|
||||||
|
private MemberDisplay creator;
|
||||||
|
|
||||||
|
public static QuickReplyListItem fromQuickReply(QuickReply quickReply) {
|
||||||
|
MemberDisplay creatorObj = MemberDisplay.fromAUserInAServer(quickReply.getCreator());
|
||||||
|
|
||||||
|
return QuickReplyListItem
|
||||||
|
.builder()
|
||||||
|
.name(quickReply.getName())
|
||||||
|
.content(quickReply.getAdditionalMessage())
|
||||||
|
.creator(creatorObj)
|
||||||
|
.anonymous(quickReply.getAnonymous())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,12 +72,14 @@ public interface ModMailThreadService {
|
|||||||
* @param threadId The id of the {@link ModMailThread} to which the reply was sent to
|
* @param threadId The id of the {@link ModMailThread} to which the reply was sent to
|
||||||
* @param text The parsed text of the reply
|
* @param text The parsed text of the reply
|
||||||
* @param message The pure {@link Message} containing the command which caused the reply
|
* @param message The pure {@link Message} containing the command which caused the reply
|
||||||
* @param anonymous Whether or nor the message should be send anonymous
|
* @param anonymous Whether or nor the message should be sent anonymous
|
||||||
* @param targetUser The {@link User} the {@link ModMailThread} is about.
|
* @param targetUser The {@link User} the {@link ModMailThread} is about.
|
||||||
* @param guild The guild the reply is created in
|
* @param guild The guild the reply is created in
|
||||||
|
* @param executingMember The member that initiates the reply
|
||||||
* @return A {@link CompletableFuture future} which completes when the message has been relayed to the DM
|
* @return A {@link CompletableFuture future} which completes when the message has been relayed to the DM
|
||||||
*/
|
*/
|
||||||
CompletableFuture<Void> loadExecutingMemberAndRelay(Long threadId, String text, Message message, boolean anonymous, User targetUser, Guild guild);
|
CompletableFuture<Void> relayMessageToDm(Long threadId, String text, Message message, boolean anonymous, User targetUser, Guild guild, Member executingMember);
|
||||||
|
CompletableFuture<Void> relayMessageToDm(Long threadId, String content, Long uniqueMessageId, boolean anonymous, User targetUser, Guild guild, Member executingMember);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the mod mail thread which means: deletes the {@link net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel} associated with the mod mail thread,
|
* Closes the mod mail thread which means: deletes the {@link net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel} associated with the mod mail thread,
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
public interface QuickReplyService {
|
||||||
|
QuickReply createQuickReply(String name, String content, Member creator, boolean anonymous);
|
||||||
|
void deleteQuickReply(String name, Guild guild);
|
||||||
|
List<QuickReply> getQuickReplies(Guild guild);
|
||||||
|
Optional<QuickReply> getQuickReply(String name, Guild guild);
|
||||||
|
List<QuickReply> getQuickRepliesContaining(String name, Guild guild);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dev.sheldan.abstracto.modmail.service.management;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.modmail.model.database.QuickReply;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface QuickReplyManagementService {
|
||||||
|
Optional<QuickReply> getQuickReplyByName(String name, Long serverId);
|
||||||
|
QuickReply createQuickReply(String name, String content, AUserInAServer creator, boolean anonymous);
|
||||||
|
void deleteQuickReply(String name, AServer server);
|
||||||
|
List<QuickReply> getQuickReplies(AServer server);
|
||||||
|
List<QuickReply> getQuickRepliesContaining(String prefix, AServer server);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto</groupId>
|
<groupId>dev.sheldan.abstracto</groupId>
|
||||||
<artifactId>abstracto-application</artifactId>
|
<artifactId>abstracto-application</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>profanity-filter</artifactId>
|
<artifactId>profanity-filter</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>profanity-filter</artifactId>
|
<artifactId>profanity-filter</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>remind</artifactId>
|
<artifactId>remind</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>remind</artifactId>
|
<artifactId>remind</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>repost-detection</artifactId>
|
<artifactId>repost-detection</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>repost-detection</artifactId>
|
<artifactId>repost-detection</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>starboard</artifactId>
|
<artifactId>starboard</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>starboard</artifactId>
|
<artifactId>starboard</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>statistic</artifactId>
|
<artifactId>statistic</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<artifactId>statistic</artifactId>
|
<artifactId>statistic</artifactId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>abstracto-modules</artifactId>
|
<artifactId>abstracto-modules</artifactId>
|
||||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||||
<version>1.6.23-SNAPSHOT</version>
|
<version>1.6.30-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user