mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-02 23:57:22 +00:00
Compare commits
5 Commits
v1.5.26
...
2024031712
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
972a2829d7 | ||
|
|
dbf5d99622 | ||
|
|
f45721ba42 | ||
|
|
9034968868 | ||
|
|
bcb9bacea5 |
@@ -12,7 +12,7 @@ An example implementation of this bot can be seen [here](https://github.com/Shel
|
||||
|
||||
|
||||
## Technologies
|
||||
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-beta.13
|
||||
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-beta.21
|
||||
* [Spring boot](https://github.com/spring-projects/spring-boot) is used as a framework to create standalone application in Java with Java EE methods. (including dependency injection and more)
|
||||
* [Hibernate](https://github.com/hibernate/hibernate-orm) is used as a reference implementation of JPA.
|
||||
* [Freemarker](https://github.com/apache/freemarker) is used as a templating engine. This is used to provide internationalization for user facing text and enable dynamic embed configuration.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -336,7 +336,8 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
RoleCalculationResult result = RoleCalculationResult
|
||||
.builder()
|
||||
.build();
|
||||
if(!Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel())) {
|
||||
boolean userChangesLevel = !Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel());
|
||||
if(userChangesLevel) {
|
||||
Integer oldLevel = aUserExperience.getCurrentLevel() != null ? aUserExperience.getCurrentLevel().getLevel() : 0;
|
||||
log.info("User {} in server {} changed level. New {}, Old {}.", member.getIdLong(),
|
||||
member.getGuild().getIdLong(), newLevel.getLevel(),
|
||||
@@ -371,7 +372,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
aUserExperience.setCurrentExperienceRole(calculatedNewRole);
|
||||
}
|
||||
aUserExperience.setMessageCount(aUserExperience.getMessageCount() + 1L);
|
||||
if(featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
|
||||
if(userChangesLevel && featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
|
||||
levelActionService.applyLevelActionsToUser(aUserExperience)
|
||||
.thenAccept(unused -> {
|
||||
log.info("Executed level actions for user {}.", userInServerId);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import dev.sheldan.abstracto.invitefilter.model.template.listener.DeletedInvite;
|
||||
import dev.sheldan.abstracto.invitefilter.model.template.listener.DeletedInvitesNotificationModel;
|
||||
import dev.sheldan.abstracto.invitefilter.service.management.AllowedInviteLinkManagement;
|
||||
import dev.sheldan.abstracto.invitefilter.service.management.FilteredInviteLinkManagement;
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionService;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -78,6 +80,9 @@ public class InviteLinkFilterServiceBean implements InviteLinkFilterService {
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ModerationActionService moderationActionService;
|
||||
|
||||
private static final Pattern INVITE_CODE_PATTERN = Pattern.compile("(?<code>[a-z0-9-]+)", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String INVITE_FILTER_METRIC = "invite.filter";
|
||||
@@ -230,10 +235,18 @@ public class InviteLinkFilterServiceBean implements InviteLinkFilterService {
|
||||
log.info("Post target {} not defined for server {} - not sending invite link deletion notification.", InviteFilterPostTarget.INVITE_DELETE_LOG.getKey(), serverId);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
boolean moderationActionsEnabled = featureModeService.featureModeActive(InviteFilterFeatureDefinition.INVITE_FILTER, serverId, InviteFilterMode.FILTER_MODERATION_ACTIONS);
|
||||
List<ModerationActionButton> moderationActionComponents = new ArrayList<>();
|
||||
if(moderationActionsEnabled && moderationActionService != null) {
|
||||
ServerUser reportedServerUser = ServerUser.fromMember(message.getMember());
|
||||
List<ModerationActionButton> moderationActions = moderationActionService.getModerationActionButtons(reportedServerUser);
|
||||
moderationActionComponents.addAll(moderationActions);
|
||||
}
|
||||
DeletedInvitesNotificationModel model = DeletedInvitesNotificationModel
|
||||
.builder()
|
||||
.author(message.getMember())
|
||||
.guild(message.getGuild())
|
||||
.moderationActionComponents(moderationActionComponents)
|
||||
.message(message)
|
||||
.channel(message.getChannel())
|
||||
.invites(groupInvites(codes))
|
||||
|
||||
@@ -11,3 +11,6 @@ abstracto.featureModes.filterNotifications.featureName=inviteFilter
|
||||
abstracto.featureModes.filterNotifications.mode=filterNotifications
|
||||
abstracto.featureModes.filterNotifications.enabled=true
|
||||
|
||||
abstracto.featureModes.filterModerationActions.featureName=inviteFilter
|
||||
abstracto.featureModes.filterModerationActions.mode=filterModerationActions
|
||||
abstracto.featureModes.filterModerationActions.enabled=false
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
<artifactId>core-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-int</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -23,6 +23,6 @@ public class InviteFilterFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(InviteFilterMode.FILTER_NOTIFICATIONS, InviteFilterMode.TRACK_USES);
|
||||
return Arrays.asList(InviteFilterMode.values());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum InviteFilterMode implements FeatureMode {
|
||||
TRACK_USES("trackUses"), FILTER_NOTIFICATIONS("filterNotifications");
|
||||
TRACK_USES("trackUses"), FILTER_NOTIFICATIONS("filterNotifications"), FILTER_MODERATION_ACTIONS("filterModerationActions");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.invitefilter.model.template.listener;
|
||||
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -17,4 +18,5 @@ public class DeletedInvitesNotificationModel {
|
||||
private Member author;
|
||||
private Message message;
|
||||
private List<DeletedInvite> invites;
|
||||
private List<ModerationActionButton> moderationActionComponents;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
@@ -70,7 +70,7 @@ public class Ban extends AbstractConditionableCommand {
|
||||
}
|
||||
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||
return banService.banUserWithNotification(member.getUser(), reason, event.getMember(), duration)
|
||||
return banService.banUserWithNotification(ServerUser.fromMember(member), reason, ServerUser.fromMember(event.getMember()), event.getGuild(), duration)
|
||||
.thenCompose(banResult -> {
|
||||
if(banResult == NOTIFICATION_FAILED) {
|
||||
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, event.getGuild().getIdLong());
|
||||
@@ -84,7 +84,7 @@ public class Ban extends AbstractConditionableCommand {
|
||||
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
||||
Long userId = Long.parseLong(userIdStr);
|
||||
return userService.retrieveUserForId(userId)
|
||||
.thenCompose(user -> banService.banUserWithNotification(user, reason, event.getMember(), duration))
|
||||
.thenCompose(user -> banService.banUserWithNotification(ServerUser.fromId(event.getGuild().getIdLong(), userId), reason, ServerUser.fromMember(event.getMember()), event.getGuild(), duration))
|
||||
.thenCompose(banResult -> {
|
||||
if(banResult == NOTIFICATION_FAILED) {
|
||||
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, event.getGuild().getIdLong());
|
||||
|
||||
@@ -2,20 +2,21 @@ package dev.sheldan.abstracto.moderation.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.config.*;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.EffectConfig;
|
||||
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.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
||||
import dev.sheldan.abstracto.moderation.service.KickServiceBean;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -47,30 +48,6 @@ public class Kick extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Member member = (Member) parameters.get(0);
|
||||
if(!member.getGuild().equals(commandContext.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
String defaultReason = templateService.renderSimpleTemplate(KICK_DEFAULT_REASON_TEMPLATE, commandContext.getGuild().getIdLong());
|
||||
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
|
||||
|
||||
KickLogModel kickLogModel = KickLogModel
|
||||
.builder()
|
||||
.kickedUser(member)
|
||||
.reason(reason)
|
||||
.guild(commandContext.getGuild())
|
||||
.channel(commandContext.getChannel())
|
||||
.member(commandContext.getAuthor())
|
||||
.build();
|
||||
kickLogModel.setKickedUser(member);
|
||||
kickLogModel.setReason(reason);
|
||||
return kickService.kickMember(member, reason, kickLogModel)
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, Member.class);
|
||||
@@ -84,17 +61,7 @@ public class Kick extends AbstractConditionableCommand {
|
||||
reason = templateService.renderSimpleTemplate(KICK_DEFAULT_REASON_TEMPLATE, event.getGuild().getIdLong());
|
||||
}
|
||||
|
||||
KickLogModel kickLogModel = KickLogModel
|
||||
.builder()
|
||||
.kickedUser(member)
|
||||
.reason(reason)
|
||||
.guild(event.getGuild())
|
||||
.channel(event.getGuildChannel())
|
||||
.member(event.getMember())
|
||||
.build();
|
||||
kickLogModel.setKickedUser(member);
|
||||
kickLogModel.setReason(reason);
|
||||
return kickService.kickMember(member, reason, kickLogModel)
|
||||
return kickService.kickMember(member, event.getMember(), reason)
|
||||
.thenCompose(unused -> interactionService.replyEmbed(KICK_RESPONSE, event))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
@@ -143,6 +110,7 @@ public class Kick extends AbstractConditionableCommand {
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.supportsEmbedException(true)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.effects(effectConfig)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -10,12 +10,17 @@ import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParame
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -24,17 +29,18 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.abstracto.moderation.model.MuteResult.NOTIFICATION_FAILED;
|
||||
import static dev.sheldan.abstracto.moderation.service.MuteService.MUTE_EFFECT_KEY;
|
||||
|
||||
@Component
|
||||
public class Mute extends AbstractConditionableCommand {
|
||||
|
||||
private static final String MUTE_DEFAULT_REASON_TEMPLATE = "mute_default_reason";
|
||||
public static final String MUTE_NOTIFICATION_NOT_POSSIBLE_TEMPLATE_KEY = "mute_notification_not_possible";
|
||||
private static final String DURATION_PARAMETER = "duration";
|
||||
private static final String MUTE_COMMAND = "mute";
|
||||
private static final String USER_PARAMETER = "user";
|
||||
@@ -53,6 +59,9 @@ public class Mute extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -64,15 +73,19 @@ public class Mute extends AbstractConditionableCommand {
|
||||
Duration duration = (Duration) parameters.get(1);
|
||||
String defaultReason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
||||
String reason = parameters.size() == 3 ? (String) parameters.get(2) : defaultReason;
|
||||
MuteContext muteLogModel = MuteContext
|
||||
.builder()
|
||||
.muteTargetDate(Instant.now().plus(duration))
|
||||
.mutedUser(member)
|
||||
.channelId(commandContext.getChannel().getIdLong())
|
||||
.reason(reason)
|
||||
.mutingUser(commandContext.getAuthor())
|
||||
.build();
|
||||
return muteService.muteMemberWithLog(muteLogModel)
|
||||
ServerUser userToMute = ServerUser.fromMember(member);
|
||||
ServerUser mutingUser = ServerUser.fromMember(commandContext.getAuthor());
|
||||
Long serverId = commandContext.getGuild().getIdLong();
|
||||
ServerChannelMessage serverChannelMessage = ServerChannelMessage.fromMessage(commandContext.getMessage());
|
||||
return muteService.muteMemberWithLog(userToMute, mutingUser, reason, duration, commandContext.getGuild(), serverChannelMessage)
|
||||
.thenCompose(muteResult -> {
|
||||
if(muteResult == NOTIFICATION_FAILED) {
|
||||
MessageToSend errorNotification = templateService.renderEmbedTemplate(MUTE_NOTIFICATION_NOT_POSSIBLE_TEMPLATE_KEY, new Object(), serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(errorNotification, commandContext.getChannel()));
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
})
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -88,16 +101,23 @@ public class Mute extends AbstractConditionableCommand {
|
||||
} else {
|
||||
reason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
||||
}
|
||||
MuteContext muteLogModel = MuteContext
|
||||
Long serverId = event.getGuild().getIdLong();
|
||||
ServerChannelMessage commandMessage = ServerChannelMessage
|
||||
.builder()
|
||||
.muteTargetDate(Instant.now().plus(duration))
|
||||
.mutedUser(targetMember)
|
||||
.reason(reason)
|
||||
.serverId(serverId)
|
||||
.channelId(event.getChannel().getIdLong())
|
||||
.mutingUser(event.getMember())
|
||||
.messageId(SnowflakeUtils.createSnowFlake())
|
||||
.build();
|
||||
return muteService.muteMemberWithLog(muteLogModel)
|
||||
.thenCompose(unused -> interactionService.replyEmbed(MUTE_RESPONSE, event))
|
||||
ServerUser userToMute = ServerUser.fromMember(targetMember);
|
||||
ServerUser mutingUser = ServerUser.fromMember(event.getMember());
|
||||
return muteService.muteMemberWithLog(userToMute, mutingUser, reason, duration, event.getGuild(), commandMessage)
|
||||
.thenCompose(muteResult -> {
|
||||
if(muteResult == NOTIFICATION_FAILED) {
|
||||
return interactionService.replyEmbed(MUTE_NOTIFICATION_NOT_POSSIBLE_TEMPLATE_KEY, new Object(), event);
|
||||
} else {
|
||||
return interactionService.replyEmbed(MUTE_RESPONSE, event);
|
||||
}
|
||||
})
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
@@ -50,7 +51,7 @@ public class UnBan extends AbstractConditionableCommand {
|
||||
String userIdStr = (String) parameters.get(0);
|
||||
Long userId = Long.parseLong(userIdStr);
|
||||
return userService.retrieveUserForId(userId)
|
||||
.thenCompose(user -> banService.unBanUserWithNotification(user, commandContext.getAuthor()))
|
||||
.thenCompose(user -> banService.unBanUserWithNotification(userId, ServerUser.fromMember(commandContext.getAuthor()), commandContext.getGuild()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ public class UnBan extends AbstractConditionableCommand {
|
||||
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, String.class);
|
||||
Long userId = Long.parseLong(userIdStr);
|
||||
return userService.retrieveUserForId(userId)
|
||||
.thenCompose(user -> banService.unBanUserWithNotification(user, event.getMember()))
|
||||
.thenCompose(user -> banService.unBanUserWithNotification(userId, ServerUser.fromMember(event.getMember()), event.getGuild()))
|
||||
.thenCompose(unused -> interactionService.replyEmbed(UN_BAN_RESPONSE, event))
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParame
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
@@ -52,8 +52,9 @@ public class UnMute extends AbstractConditionableCommand {
|
||||
if(!member.getGuild().equals(commandContext.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(member);
|
||||
return muteService.unMuteUser(userToUnMute, commandContext.getAuthor()).thenApply(aVoid ->
|
||||
ServerUser userToUnmute = ServerUser.fromMember(member);
|
||||
ServerUser unMutingMember = ServerUser.fromMember(commandContext.getAuthor());
|
||||
return muteService.unMuteUser(userToUnmute, unMutingMember, commandContext.getGuild()).thenApply(aVoid ->
|
||||
CommandResult.fromSuccess()
|
||||
);
|
||||
}
|
||||
@@ -64,8 +65,9 @@ public class UnMute extends AbstractConditionableCommand {
|
||||
if(!targetMember.getGuild().equals(event.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(targetMember);
|
||||
return muteService.unMuteUser(userToUnMute, event.getMember())
|
||||
ServerUser userToUnmute = ServerUser.fromMember(targetMember);
|
||||
ServerUser unMutingMember = ServerUser.fromMember(event.getMember());
|
||||
return muteService.unMuteUser(userToUnmute, unMutingMember, event.getGuild())
|
||||
.thenCompose(unused -> interactionService.replyEmbed(UN_MUTE_RESPONSE, event))
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParame
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnContext;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -59,16 +61,8 @@ public class Warn extends AbstractConditionableCommand {
|
||||
}
|
||||
String defaultReason = templateService.renderSimpleTemplate(WARN_DEFAULT_REASON_TEMPLATE, commandContext.getGuild().getIdLong());
|
||||
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
|
||||
WarnContext warnLogModel = WarnContext
|
||||
.builder()
|
||||
.reason(reason)
|
||||
.warnedMember(member)
|
||||
.channel(commandContext.getChannel())
|
||||
.member(commandContext.getAuthor())
|
||||
.guild(commandContext.getGuild())
|
||||
.message(commandContext.getMessage())
|
||||
.build();
|
||||
return warnService.warnUserWithLog(warnLogModel)
|
||||
ServerChannelMessage commandMessage = ServerChannelMessage.fromMessage(commandContext.getMessage());
|
||||
return warnService.warnUserWithLog(commandContext.getGuild(), ServerUser.fromMember(member), ServerUser.fromMember(commandContext.getAuthor()), reason, commandMessage)
|
||||
.thenApply(warning -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -84,15 +78,13 @@ public class Warn extends AbstractConditionableCommand {
|
||||
} else {
|
||||
reason = templateService.renderSimpleTemplate(WARN_DEFAULT_REASON_TEMPLATE, event.getGuild().getIdLong());
|
||||
}
|
||||
WarnContext warnLogModel = WarnContext
|
||||
ServerChannelMessage commandMessage = ServerChannelMessage
|
||||
.builder()
|
||||
.reason(reason)
|
||||
.warnedMember(member)
|
||||
.member(event.getMember())
|
||||
.channel(event.getGuildChannel())
|
||||
.guild(event.getGuild())
|
||||
.serverId(event.getGuild().getIdLong())
|
||||
.channelId(event.getChannel().getIdLong())
|
||||
.messageId(SnowflakeUtils.createSnowFlake())
|
||||
.build();
|
||||
return warnService.warnUserWithLog(warnLogModel)
|
||||
return warnService.warnUserWithLog(event.getGuild(), ServerUser.fromMember(member), ServerUser.fromMember(event.getMember()), reason, commandMessage)
|
||||
.thenCompose(unused -> interactionService.replyEmbed(WARN_RESPONSE, event))
|
||||
.thenApply(warning -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalConfigPayload;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionBanPayload;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionBanModalModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionServiceBean;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class BanModerationActionListener implements ButtonClickedListener {
|
||||
|
||||
@Autowired
|
||||
private ModalService modalService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Autowired
|
||||
private BanModerationActionListener self;
|
||||
|
||||
private static final String BAN_REASON_MODERATION_ACTION_MODAL = "moderationAction_ban";
|
||||
public static final String BAN_MODAL_ORIGIN = "BAN_MODERATION_ACTION_ORIGIN";
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
if(ModerationActionServiceBean.BAN_ACTION.equals(payload.getAction())) {
|
||||
log.info("Handling ban button interaction by user {} in server {} for user {}.",
|
||||
payload.getUser().getUserId(), payload.getUser().getServerId(), model.getEvent().getMember().getIdLong());
|
||||
String modalId = componentService.generateComponentId();
|
||||
String reasonInputId = componentService.generateComponentId();
|
||||
String durationInputId = componentService.generateComponentId();
|
||||
ModerationActionBanModalModel modalModel = ModerationActionBanModalModel
|
||||
.builder()
|
||||
.modalId(modalId)
|
||||
.durationComponentId(durationInputId)
|
||||
.reasonComponentId(reasonInputId)
|
||||
.build();
|
||||
modalService.replyModal(model.getEvent(), BAN_REASON_MODERATION_ACTION_MODAL, modalModel).thenAccept(unused -> {
|
||||
log.info("Returned ban reason moderation action modal for user {} towards user {} in server {}.",
|
||||
payload.getUser().getUserId(), model.getEvent().getMember().getIdLong(), model.getServerId());
|
||||
self.persistBanModerationActionPayload(payload.getUser(), reasonInputId, modalId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to show modal for ban moderation action.", throwable);
|
||||
return null;
|
||||
});
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
} else {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistBanModerationActionPayload(ServerUser userToBan, String reasonInput, String modalId) {
|
||||
ModerationActionBanPayload payload = ModerationActionBanPayload
|
||||
.builder()
|
||||
.bannedUserId(userToBan.getUserId())
|
||||
.serverId(userToBan.getServerId())
|
||||
.reasonInputId(reasonInput)
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
ModalConfigPayload payloadConfig = ModalConfigPayload
|
||||
.builder()
|
||||
.modalPayload(payload)
|
||||
.origin(BAN_MODAL_ORIGIN)
|
||||
.payloadType(payload.getClass())
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
componentPayloadManagementService.createModalPayload(payloadConfig, userToBan.getServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
if(ModerationActionServiceBean.MODERATION_ACTION_ORIGIN.equals(model.getOrigin())){
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
return ModerationActionServiceBean.BAN_ACTION.equals(payload.getAction());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MODERATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean autoAcknowledgeEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionExceptionService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListener;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionBanPayload;
|
||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class BanModerationActionModalListener implements ModalInteractionListener {
|
||||
|
||||
private static final String KICK_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE = "moderationAction_ban_response";
|
||||
private static final String DEFAULT_BAN_REASON_TEMPLATE_KEY = "ban_default_reason";
|
||||
|
||||
@Autowired
|
||||
private BanService banService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private InteractionExceptionService interactionExceptionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ModalInteractionListenerModel model) {
|
||||
return BanModerationActionListener.BAN_MODAL_ORIGIN.equals(model.getOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalInteractionListenerResult execute(ModalInteractionListenerModel model) {
|
||||
ModerationActionBanPayload payload = (ModerationActionBanPayload) model.getDeserializedPayload();
|
||||
ServerUser userBeingBanned = ServerUser
|
||||
.builder()
|
||||
.userId(payload.getBannedUserId())
|
||||
.serverId(payload.getServerId())
|
||||
.build();
|
||||
|
||||
ServerUser kickingUser = ServerUser.fromMember(model.getEvent().getMember());
|
||||
|
||||
String duration = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Duration messageDeletionDuration;
|
||||
if(duration != null) {
|
||||
messageDeletionDuration = ParseUtils.parseDuration(duration.trim());
|
||||
} else {
|
||||
messageDeletionDuration = null;
|
||||
}
|
||||
String reason;
|
||||
String tempReason = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if(StringUtils.isBlank(tempReason)) {
|
||||
reason = templateService.renderSimpleTemplate(DEFAULT_BAN_REASON_TEMPLATE_KEY);
|
||||
} else {
|
||||
reason = tempReason;
|
||||
}
|
||||
log.debug("Handling ban moderation action modal interaction by user {} in server {}.", kickingUser.getUserId(), kickingUser.getServerId());
|
||||
model.getEvent().deferReply(true).queue(interactionHook -> {
|
||||
banService.banUserWithNotification(userBeingBanned, reason, kickingUser, model.getEvent().getGuild(), messageDeletionDuration)
|
||||
.thenCompose((future) -> FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(KICK_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE, new Object(), model.getEvent().getInteraction().getHook())))
|
||||
.thenAccept(unused -> {
|
||||
log.info("Kicked user {} from server {}. Performed by user {}.", userBeingBanned.getUserId(), kickingUser.getServerId(), kickingUser.getUserId());
|
||||
}).exceptionally(throwable -> {
|
||||
interactionExceptionService.reportExceptionToInteraction(throwable, model, this);
|
||||
log.error("Failed to kick user {} from server {}. Performed by user {}.", userBeingBanned.getUserId(), kickingUser.getServerId(), kickingUser.getUserId(), throwable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
return ModalInteractionListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MODERATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.jda.RoleAddedListener;
|
||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.listener.RoleAddedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
@@ -23,6 +24,7 @@ import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashMap;
|
||||
@@ -77,7 +79,8 @@ public class HoneyPotRoleAddedListener implements RoleAddedListener {
|
||||
.roleDisplay(RoleDisplay.fromRole(model.getRole()))
|
||||
.build();
|
||||
String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel);
|
||||
banService.banUserWithNotification(model.getTargetMember().getUser(), banReason, model.getTargetMember().getGuild().getSelfMember(), null).thenAccept(banResult -> {
|
||||
banService.banUserWithNotification(model.getTargetUser(), banReason, ServerUser.fromMember(model.getTargetMember().getGuild().getSelfMember()),
|
||||
model.getTargetMember().getGuild(), Duration.ofDays(7)).thenAccept(banResult -> {
|
||||
log.info("Banned user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId());
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to ban user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId(), throwable);
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalConfigPayload;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionKickPayload;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionKickModalModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionServiceBean;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class KickModerationActionListener implements ButtonClickedListener {
|
||||
|
||||
@Autowired
|
||||
private ModalService modalService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Autowired
|
||||
private KickModerationActionListener self;
|
||||
|
||||
private static final String KICK_REASON_MODERATION_ACTION_MODAL = "moderationAction_kick";
|
||||
public static final String KICK_MODAL_ORIGIN = "KICK_MODERATION_ACTION_ORIGIN";
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
if(ModerationActionServiceBean.KICK_ACTION.equals(payload.getAction())) {
|
||||
log.info("Handling kick button interaction by user {} in server {} for user {}.",
|
||||
payload.getUser().getUserId(), payload.getUser().getServerId(), model.getEvent().getMember().getIdLong());
|
||||
String modalId = componentService.generateComponentId();
|
||||
String reasonInputId = componentService.generateComponentId();
|
||||
ModerationActionKickModalModel modalModel = ModerationActionKickModalModel
|
||||
.builder()
|
||||
.modalId(modalId)
|
||||
.reasonComponentId(reasonInputId)
|
||||
.build();
|
||||
modalService.replyModal(model.getEvent(), KICK_REASON_MODERATION_ACTION_MODAL, modalModel).thenAccept(unused -> {
|
||||
log.info("Returned kick reason moderation action modal for user {} towards user {} in server {}.",
|
||||
payload.getUser().getUserId(), model.getEvent().getMember().getIdLong(), model.getServerId());
|
||||
self.persistKickModerationActionPayload(payload.getUser(), reasonInputId, modalId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to show modal for kick moderation action.", throwable);
|
||||
return null;
|
||||
});
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
} else {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistKickModerationActionPayload(ServerUser userToKick, String reasonInput, String modalId) {
|
||||
ModerationActionKickPayload payload = ModerationActionKickPayload
|
||||
.builder()
|
||||
.kickedUserId(userToKick.getUserId())
|
||||
.serverId(userToKick.getServerId())
|
||||
.reasonInputId(reasonInput)
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
ModalConfigPayload payloadConfig = ModalConfigPayload
|
||||
.builder()
|
||||
.modalPayload(payload)
|
||||
.origin(KICK_MODAL_ORIGIN)
|
||||
.payloadType(payload.getClass())
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
componentPayloadManagementService.createModalPayload(payloadConfig, userToKick.getServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
if(ModerationActionServiceBean.MODERATION_ACTION_ORIGIN.equals(model.getOrigin())){
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
return ModerationActionServiceBean.KICK_ACTION.equals(payload.getAction());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MODERATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean autoAcknowledgeEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionExceptionService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListener;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionKickPayload;
|
||||
import dev.sheldan.abstracto.moderation.service.KickService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class KickModerationActionModalListener implements ModalInteractionListener {
|
||||
|
||||
private static final String KICK_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE = "moderationAction_kick_response";
|
||||
|
||||
@Autowired
|
||||
private KickService kickService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private InteractionExceptionService interactionExceptionService;
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ModalInteractionListenerModel model) {
|
||||
return KickModerationActionListener.KICK_MODAL_ORIGIN.equals(model.getOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalInteractionListenerResult execute(ModalInteractionListenerModel model) {
|
||||
ModerationActionKickPayload payload = (ModerationActionKickPayload) model.getDeserializedPayload();
|
||||
ServerUser userBeingKicked = ServerUser
|
||||
.builder()
|
||||
.userId(payload.getKickedUserId())
|
||||
.serverId(payload.getServerId())
|
||||
.build();
|
||||
|
||||
ServerUser kickingUser = ServerUser.fromMember(model.getEvent().getMember());
|
||||
String reason = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
log.debug("Handling kick moderation action modal interaction by user {} in server {}.", kickingUser.getUserId(), kickingUser.getServerId());
|
||||
model.getEvent().deferReply(true).queue(interactionHook -> {
|
||||
kickService.kickMember(model.getEvent().getGuild(), userBeingKicked, reason, kickingUser)
|
||||
.thenCompose((future) -> FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(KICK_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE, new Object(), model.getEvent().getInteraction().getHook())))
|
||||
.thenAccept(unused -> {
|
||||
log.info("Kicked user {} from server {}. Performed by user {}.", userBeingKicked.getUserId(), kickingUser.getServerId(), kickingUser.getUserId());
|
||||
}).exceptionally(throwable -> {
|
||||
interactionExceptionService.reportExceptionToInteraction(throwable, model, this);
|
||||
log.error("Failed to kick user {} from server {}. Performed by user {}.", userBeingKicked.getUserId(), kickingUser.getServerId(), kickingUser.getUserId(), throwable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
return ModalInteractionListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MODERATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMemberTimeoutUpdatedListener;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.listener.MemberTimeoutUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
@@ -116,8 +117,8 @@ public class MemberTimeoutListener implements AsyncMemberTimeoutUpdatedListener
|
||||
.builder()
|
||||
.muteTargetDate(model.getNewTimeout() != null ? model.getNewTimeout().toInstant() : null)
|
||||
.oldMuteTargetDate(model.getOldTimeout() != null ? model.getOldTimeout().toInstant() : null)
|
||||
.mutingUser(future.isCompletedExceptionally() ? null : future.join())
|
||||
.mutedUser(model.getMember())
|
||||
.mutingUser(future.isCompletedExceptionally() ? null : MemberDisplay.fromMember(future.join()))
|
||||
.mutedUser(MemberDisplay.fromMember(model.getMember()))
|
||||
.reason(reason)
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MuteServiceBean.MUTE_LOG_TEMPLATE, muteLogModel, guild.getIdLong());
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalConfigPayload;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionMutePayload;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionMuteModalModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionServiceBean;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MuteModerationActionListener implements ButtonClickedListener {
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private ModalService modalService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Autowired
|
||||
private MuteModerationActionListener self;
|
||||
|
||||
private static final String MUTE_REASON_MODERATION_ACTION_MODAL = "moderationAction_mute";
|
||||
public static final String MUTE_MODAL_ORIGIN = "MUTE_MODERATION_ACTION_ORIGIN";
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
if(ModerationActionServiceBean.MUTE_ACTION.equals(payload.getAction())) {
|
||||
log.info("Handling mute button interaction by user {} in server {} for user {}.",
|
||||
payload.getUser().getUserId(), payload.getUser().getServerId(), model.getEvent().getMember().getIdLong());
|
||||
String modalId = componentService.generateComponentId();
|
||||
String reasonInputId = componentService.generateComponentId();
|
||||
String durationInputId = componentService.generateComponentId();
|
||||
ModerationActionMuteModalModel modalModel = ModerationActionMuteModalModel
|
||||
.builder()
|
||||
.modalId(modalId)
|
||||
.durationComponentId(durationInputId)
|
||||
.reasonComponentId(reasonInputId)
|
||||
.build();
|
||||
modalService.replyModal(model.getEvent(), MUTE_REASON_MODERATION_ACTION_MODAL, modalModel).thenAccept(unused -> {
|
||||
log.info("Returned mute reason moderation action modal for user {} towards user {} in server {}.",
|
||||
payload.getUser().getUserId(), model.getEvent().getMember().getIdLong(), model.getServerId());
|
||||
self.persistMuteModerationActionPayload(payload.getUser(), reasonInputId, modalId, durationInputId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to show modal for mute moderation action.", throwable);
|
||||
return null;
|
||||
});
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
} else {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistMuteModerationActionPayload(ServerUser userToMute, String reasonInput, String modalId, String durationInputId) {
|
||||
ModerationActionMutePayload payload = ModerationActionMutePayload
|
||||
.builder()
|
||||
.mutedUserId(userToMute.getUserId())
|
||||
.serverId(userToMute.getServerId())
|
||||
.reasonInputId(reasonInput)
|
||||
.durationInputId(durationInputId)
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
ModalConfigPayload payloadConfig = ModalConfigPayload
|
||||
.builder()
|
||||
.modalPayload(payload)
|
||||
.origin(MUTE_MODAL_ORIGIN)
|
||||
.payloadType(payload.getClass())
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
componentPayloadManagementService.createModalPayload(payloadConfig, userToMute.getServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
if(ModerationActionServiceBean.MODERATION_ACTION_ORIGIN.equals(model.getOrigin())){
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
return ModerationActionServiceBean.MUTE_ACTION.equals(payload.getAction());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MUTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean autoAcknowledgeEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionExceptionService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListener;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionMutePayload;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static dev.sheldan.abstracto.moderation.command.Mute.MUTE_NOTIFICATION_NOT_POSSIBLE_TEMPLATE_KEY;
|
||||
import static dev.sheldan.abstracto.moderation.model.MuteResult.NOTIFICATION_FAILED;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MuteModerationActionModalListener implements ModalInteractionListener {
|
||||
|
||||
private static final String MUTE_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE = "moderationAction_mute_response";
|
||||
|
||||
@Autowired
|
||||
private MuteService muteService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private InteractionExceptionService interactionExceptionService;
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ModalInteractionListenerModel model) {
|
||||
return MuteModerationActionListener.MUTE_MODAL_ORIGIN.equals(model.getOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalInteractionListenerResult execute(ModalInteractionListenerModel model) {
|
||||
ModerationActionMutePayload payload = (ModerationActionMutePayload) model.getDeserializedPayload();
|
||||
ServerUser userBeingMuted = ServerUser
|
||||
.builder()
|
||||
.userId(payload.getMutedUserId())
|
||||
.serverId(payload.getServerId())
|
||||
.build();
|
||||
|
||||
ServerUser mutingUser = ServerUser.fromMember(model.getEvent().getMember());
|
||||
String reason = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
String duration = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Duration muteDuration;
|
||||
if(duration != null) {
|
||||
muteDuration = ParseUtils.parseDuration(duration.trim());
|
||||
} else {
|
||||
muteDuration = Duration.ofDays(Member.MAX_TIME_OUT_LENGTH);
|
||||
}
|
||||
ServerChannelMessage serverChannelMessage = ServerChannelMessage.fromMessage(model.getEvent().getMessage());
|
||||
log.debug("Handling mute moderation action modal interaction by user {} in server {}.", mutingUser.getUserId(), mutingUser.getServerId());
|
||||
model.getEvent().deferReply(true).queue(interactionHook -> {
|
||||
muteService.muteMemberWithLog(userBeingMuted, mutingUser, reason, muteDuration, model.getEvent().getGuild(), serverChannelMessage)
|
||||
.thenCompose((future) -> {
|
||||
if(future == NOTIFICATION_FAILED) {
|
||||
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(MUTE_NOTIFICATION_NOT_POSSIBLE_TEMPLATE_KEY, new Object(), model.getEvent().getInteraction().getHook()));
|
||||
} else {
|
||||
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(MUTE_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE, new Object(), model.getEvent().getInteraction().getHook()));
|
||||
}
|
||||
})
|
||||
.thenAccept(unused -> {
|
||||
log.info("Muted user {} in server {}. Performed by user {}.", userBeingMuted.getUserId(), mutingUser.getServerId(), mutingUser.getUserId());
|
||||
}).exceptionally(throwable -> {
|
||||
interactionExceptionService.reportExceptionToInteraction(throwable, model, this);
|
||||
log.error("Failed to mute user {} in server {}. Performed by user {}.", userBeingMuted.getUserId(), mutingUser.getServerId(), mutingUser.getUserId(), throwable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
return ModalInteractionListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MUTING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalConfigPayload;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionWarnPayload;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionWarnModalModel;
|
||||
import dev.sheldan.abstracto.moderation.service.ModerationActionServiceBean;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WarnModerationActionListener implements ButtonClickedListener {
|
||||
|
||||
@Autowired
|
||||
private ModalService modalService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Autowired
|
||||
private WarnModerationActionListener self;
|
||||
|
||||
private static final String WARN_REASON_MODERATION_ACTION_MODAL = "moderationAction_warn";
|
||||
public static final String WARN_MODAL_ORIGIN = "WARN_MODERATION_ACTION_ORIGIN";
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
if(ModerationActionServiceBean.WARN_ACTION.equals(payload.getAction())) {
|
||||
log.info("Handling warn button interaction by user {} in server {} for user {}.",
|
||||
payload.getUser().getUserId(), payload.getUser().getServerId(), model.getEvent().getMember().getIdLong());
|
||||
String modalId = componentService.generateComponentId();
|
||||
String reasonInputId = componentService.generateComponentId();
|
||||
ModerationActionWarnModalModel modalModel = ModerationActionWarnModalModel
|
||||
.builder()
|
||||
.modalId(modalId)
|
||||
.reasonComponentId(reasonInputId)
|
||||
.build();
|
||||
modalService.replyModal(model.getEvent(), WARN_REASON_MODERATION_ACTION_MODAL, modalModel).thenAccept(unused -> {
|
||||
log.info("Returned warn reason moderation action modal for user {} towards user {} in server {}.",
|
||||
payload.getUser().getUserId(), model.getEvent().getMember().getIdLong(), model.getServerId());
|
||||
self.persistWarnModerationActionPayload(payload.getUser(), reasonInputId, modalId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to show modal for warn moderation action.", throwable);
|
||||
return null;
|
||||
});
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
} else {
|
||||
return ButtonClickedListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistWarnModerationActionPayload(ServerUser userToWarn, String reasonInput, String modalId) {
|
||||
ModerationActionWarnPayload payload = ModerationActionWarnPayload
|
||||
.builder()
|
||||
.warnedUserId(userToWarn.getUserId())
|
||||
.serverId(userToWarn.getServerId())
|
||||
.reasonInputId(reasonInput)
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
ModalConfigPayload payloadConfig = ModalConfigPayload
|
||||
.builder()
|
||||
.modalPayload(payload)
|
||||
.origin(WARN_MODAL_ORIGIN)
|
||||
.payloadType(payload.getClass())
|
||||
.modalId(modalId)
|
||||
.build();
|
||||
componentPayloadManagementService.createModalPayload(payloadConfig, userToWarn.getServerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
if(ModerationActionServiceBean.MODERATION_ACTION_ORIGIN.equals(model.getOrigin())){
|
||||
ModerationActionPayloadModel payload = (ModerationActionPayloadModel) model.getDeserializedPayload();
|
||||
return ModerationActionServiceBean.WARN_ACTION.equals(payload.getAction());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean autoAcknowledgeEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionExceptionService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListener;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.modal.listener.ModalInteractionListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.interaction.ModerationActionWarnPayload;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.moderation.command.Warn.WARN_DEFAULT_REASON_TEMPLATE;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WarnModerationActionModalListener implements ModalInteractionListener {
|
||||
|
||||
private static final String WARN_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE = "moderationAction_warn_response";
|
||||
|
||||
@Autowired
|
||||
private WarnService warnService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private InteractionExceptionService interactionExceptionService;
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ModalInteractionListenerModel model) {
|
||||
return WarnModerationActionListener.WARN_MODAL_ORIGIN.equals(model.getOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalInteractionListenerResult execute(ModalInteractionListenerModel model) {
|
||||
ModerationActionWarnPayload payload = (ModerationActionWarnPayload) model.getDeserializedPayload();
|
||||
ServerUser userBeingWarned = ServerUser
|
||||
.builder()
|
||||
.userId(payload.getWarnedUserId())
|
||||
.serverId(payload.getServerId())
|
||||
.build();
|
||||
|
||||
ServerUser warningUser = ServerUser.fromMember(model.getEvent().getMember());
|
||||
String reason;
|
||||
String tempReason = model
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if(StringUtils.isBlank(tempReason)) {
|
||||
reason = templateService.renderSimpleTemplate(WARN_DEFAULT_REASON_TEMPLATE, model.getServerId());
|
||||
} else {
|
||||
reason = tempReason;
|
||||
}
|
||||
ServerChannelMessage serverChannelMessage = ServerChannelMessage.fromMessage(model.getEvent().getMessage());
|
||||
log.debug("Handling warn moderation action modal interaction by user {} in server {}.", warningUser.getUserId(), warningUser.getServerId());
|
||||
model.getEvent().deferReply(true).queue(interactionHook -> {
|
||||
warnService.warnUserWithLog(model.getEvent().getGuild(), userBeingWarned, warningUser, reason, serverChannelMessage)
|
||||
.thenCompose((future) -> FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(WARN_MODERATION_ACTION_MODAL_RESPONSE_TEMPLATE, new Object(), model.getEvent().getInteraction().getHook())))
|
||||
.thenAccept(unused -> {
|
||||
log.info("Warned user {} in server {}. Performed by user {}.", userBeingWarned.getUserId(), warningUser.getServerId(), warningUser.getUserId());
|
||||
}).exceptionally(throwable -> {
|
||||
interactionExceptionService.reportExceptionToInteraction(throwable, model, this);
|
||||
log.error("Failed to warn user {} from server {}. Performed by user {}.", userBeingWarned.getUserId(), warningUser.getServerId(), warningUser.getUserId(), throwable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
return ModalInteractionListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.WARNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
@@ -85,8 +87,8 @@ public class BanReasonUpdatedListener implements InfractionUpdatedDescriptionLis
|
||||
.orElse(Duration.ZERO);
|
||||
BanLog banLog = BanLog
|
||||
.builder()
|
||||
.bannedUser(infractionUser.isCompletedExceptionally() ? null : infractionUser.join())
|
||||
.banningMember(infractionCreator.isCompletedExceptionally() ? null : infractionCreator.join())
|
||||
.bannedUser(infractionUser.isCompletedExceptionally() ? null : UserDisplay.fromUser(infractionUser.join()))
|
||||
.banningMember(infractionCreator.isCompletedExceptionally() ? null : MemberDisplay.fromMember(infractionCreator.join()))
|
||||
.deletionDuration(deletionDuration)
|
||||
.reason(model.getNewDescription())
|
||||
.build();
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.GuildService;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
@@ -14,7 +15,7 @@ import dev.sheldan.abstracto.moderation.listener.InfractionUpdatedDescriptionLis
|
||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.model.listener.InfractionDescriptionEventModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnContext;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnLogModel;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnServiceBean;
|
||||
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
||||
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
||||
@@ -82,15 +83,14 @@ public class WarnReasonUpdatedListener implements InfractionUpdatedDescriptionLi
|
||||
Guild guild = guildService.getGuildById(model.getServerId());
|
||||
Infraction infraction = infractionManagementService.loadInfraction(model.getInfractionId());
|
||||
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(model.getServerId(), infraction.getLogChannel().getId());
|
||||
WarnContext context = WarnContext
|
||||
WarnLogModel context = WarnLogModel
|
||||
.builder()
|
||||
.warnedMember(warnedUser.isCompletedExceptionally() ? null : warnedUser.join())
|
||||
.member(warningUser.isCompletedExceptionally() ? null : warningUser.join())
|
||||
.warnedMember(warnedUser.isCompletedExceptionally() ? null : MemberDisplay.fromMember(warnedUser.join()))
|
||||
.warningMember(warningUser.isCompletedExceptionally() ? null : MemberDisplay.fromMember(warningUser.join()))
|
||||
.reason(model.getNewDescription())
|
||||
.warnId(warnId)
|
||||
.guild(guild)
|
||||
.build();
|
||||
MessageToSend message = warnService.renderMessageModel(context);
|
||||
MessageToSend message = warnService.renderMessageModel(context, guild.getIdLong());
|
||||
messageService.editMessageInChannel(messageChannel, message, infraction.getLogMessageId())
|
||||
.thenAccept(unused1 -> returningFuture.complete(DefaultListenerResult.PROCESSED))
|
||||
.exceptionally(throwable1 -> {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
@@ -60,32 +63,31 @@ public class BanServiceBean implements BanService {
|
||||
private InfractionService infractionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<BanResult> banUserWithNotification(User user, String reason, Member banningMember, Duration deletionDuration) {
|
||||
public CompletableFuture<BanResult> banUserWithNotification(ServerUser userToBeBanned, String reason, ServerUser banningUser, Guild guild, Duration deletionDuration) {
|
||||
BanLog banLog = BanLog
|
||||
.builder()
|
||||
.bannedUser(user)
|
||||
.banningMember(banningMember)
|
||||
.bannedUser(UserDisplay.fromServerUser(userToBeBanned))
|
||||
.banningMember(MemberDisplay.fromServerUser(banningUser))
|
||||
.deletionDuration(deletionDuration)
|
||||
.reason(reason)
|
||||
.build();
|
||||
Guild guild = banningMember.getGuild();
|
||||
BanResult[] result = {BanResult.SUCCESSFUL};
|
||||
return sendBanNotification(user, reason, guild)
|
||||
return sendBanNotification(userToBeBanned, reason, guild)
|
||||
.exceptionally(throwable -> {
|
||||
result[0] = BanResult.NOTIFICATION_FAILED;
|
||||
return null;
|
||||
})
|
||||
.thenCompose(unused -> banUser(guild, user, deletionDuration, reason))
|
||||
.thenCompose(unused -> banUser(guild, userToBeBanned, deletionDuration, reason))
|
||||
.thenCompose(unused -> sendBanLogMessage(banLog, guild.getIdLong()))
|
||||
.thenAccept(banLogMessage -> self.evaluateAndStoreInfraction(user, guild, reason, banningMember, banLogMessage, deletionDuration))
|
||||
.thenAccept(banLogMessage -> self.evaluateAndStoreInfraction(userToBeBanned, guild, reason, banningUser, banLogMessage, deletionDuration))
|
||||
.thenApply(unused -> result[0]);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(User user, Guild guild, String reason, Member banningMember, Message banLogMessage, Duration deletionDuration) {
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(ServerUser user, Guild guild, String reason, ServerUser banningMember, Message banLogMessage, Duration deletionDuration) {
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, guild.getIdLong())) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(ModerationFeatureConfig.BAN_INFRACTION_POINTS, guild.getIdLong());
|
||||
AUserInAServer bannedUser = userInServerManagementService.loadOrCreateUser(guild.getIdLong(), user.getIdLong());
|
||||
AUserInAServer bannedUser = userInServerManagementService.loadOrCreateUser(guild.getIdLong(), user.getUserId());
|
||||
AUserInAServer banningUser = userInServerManagementService.loadOrCreateUser(banningMember);
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
if(deletionDuration == null) {
|
||||
@@ -99,47 +101,46 @@ public class BanServiceBean implements BanService {
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendBanNotification(User user, String reason, Guild guild) {
|
||||
private CompletableFuture<Void> sendBanNotification(ServerUser serverUser, String reason, Guild guild) {
|
||||
BanNotificationModel model = BanNotificationModel
|
||||
.builder()
|
||||
.serverName(guild.getName())
|
||||
.reason(reason)
|
||||
.build();
|
||||
String message = templateService.renderTemplate(BAN_NOTIFICATION, model, guild.getIdLong());
|
||||
return messageService.sendMessageToUser(user, message).thenAccept(message1 -> {});
|
||||
return messageService.sendMessageToUser(serverUser, message).thenAccept(message1 -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> unBanUserWithNotification(User user, Member unBanningMember) {
|
||||
Guild guild = unBanningMember.getGuild();
|
||||
public CompletableFuture<Void> unBanUserWithNotification(Long userId, ServerUser unBanningMember, Guild guild) {
|
||||
UnBanLog banLog = UnBanLog
|
||||
.builder()
|
||||
.bannedUser(user)
|
||||
.unBanningMember(unBanningMember)
|
||||
.bannedUser(UserDisplay.fromId(userId))
|
||||
.unBanningMember(MemberDisplay.fromServerUser(unBanningMember))
|
||||
.build();
|
||||
return unbanUser(guild, user)
|
||||
return unbanUser(guild, userId)
|
||||
.thenCompose(unused -> self.sendUnBanLogMessage(banLog, guild.getIdLong(), UN_BAN_LOG_TEMPLATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> banUser(Guild guild, User user, Duration deletionDuration, String reason) {
|
||||
log.info("Banning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
public CompletableFuture<Void> banUser(Guild guild, ServerUser userToBeBanned, Duration deletionDuration, String reason) {
|
||||
log.info("Banning user {} in guild {}.", userToBeBanned.getUserId(), guild.getId());
|
||||
if(deletionDuration == null || deletionDuration.isNegative()) {
|
||||
deletionDuration = Duration.ZERO;
|
||||
}
|
||||
return guild.ban(user, (int) deletionDuration.getSeconds(), TimeUnit.SECONDS).reason(reason).submit();
|
||||
return guild.ban(UserSnowflake.fromId(userToBeBanned.getUserId()), (int) deletionDuration.getSeconds(), TimeUnit.SECONDS).reason(reason).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> unbanUser(Guild guild, User user) {
|
||||
log.info("Unbanning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
return guild.unban(user).submit();
|
||||
public CompletableFuture<Void> unbanUser(Guild guild, Long userId) {
|
||||
log.info("Unbanning user {} in guild {}.", userId, guild.getId());
|
||||
return guild.unban(UserSnowflake.fromId(userId)).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> softBanUser(Guild guild, User user, Duration delDays) {
|
||||
public CompletableFuture<Void> softBanUser(Guild guild, ServerUser user, Duration delDays) {
|
||||
return banUser(guild, user, delDays, "")
|
||||
.thenCompose(unused -> unbanUser(guild, user));
|
||||
.thenCompose(unused -> unbanUser(guild, user.getUserId()));
|
||||
}
|
||||
|
||||
public CompletableFuture<Message> sendBanLogMessage(BanLog banLog, Long guildId) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
@@ -17,6 +19,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.UserSnowflake;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -52,31 +55,72 @@ public class KickServiceBean implements KickService {
|
||||
private KickServiceBean self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> kickMember(Member member, String reason, KickLogModel kickLogModel) {
|
||||
Guild guild = member.getGuild();
|
||||
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), guild.getIdLong());
|
||||
CompletableFuture<Void> kickFuture = guild.kick(member, reason).submit();
|
||||
CompletableFuture<Message> logFuture = this.sendKickLog(kickLogModel);
|
||||
public CompletableFuture<Void> kickMember(Member kickedMember, Member kickingMember, String reason) {
|
||||
Guild guild = kickedMember.getGuild();
|
||||
log.info("Kicking user {} from guild {}", kickedMember.getUser().getIdLong(), guild.getIdLong());
|
||||
CompletableFuture<Void> kickFuture = guild.kick(kickedMember, reason).submit();
|
||||
CompletableFuture<Message> logFuture = sendKickLog(kickedMember, kickingMember, reason, guild.getIdLong());
|
||||
return CompletableFuture.allOf(kickFuture, logFuture)
|
||||
.thenAccept(unused -> self.storeInfraction(member, reason, kickLogModel, guild, logFuture.join()));
|
||||
.thenAccept(unused -> self.storeInfraction(kickedMember, kickingMember, reason, logFuture.join(), guild.getIdLong()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> kickMember(Guild guild, ServerUser kickedUser, String reason, ServerUser kickingUser) {
|
||||
CompletableFuture<Void> kickFuture = guild.kick(UserSnowflake.fromId(kickedUser.getUserId())).submit();
|
||||
CompletableFuture<Message> logFuture = sendKickLog(kickedUser, kickingUser, reason, guild.getIdLong());
|
||||
return CompletableFuture.allOf(kickFuture, logFuture)
|
||||
.thenAccept(unused -> self.storeInfraction(kickedUser, kickingUser, reason, logFuture.join(), guild.getIdLong()));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Long> storeInfraction(Member member, String reason, KickLogModel kickLogModel, Guild guild, Message logMessage) {
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, guild.getIdLong())) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(ModerationFeatureConfig.KICK_INFRACTION_POINTS, guild.getIdLong());
|
||||
public CompletableFuture<Long> storeInfraction(Member member, Member kickingMember, String reason, Message logMessage, Long serverId) {
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(ModerationFeatureConfig.KICK_INFRACTION_POINTS, serverId);
|
||||
AUserInAServer kickedUser = userInServerManagementService.loadOrCreateUser(member);
|
||||
AUserInAServer kickingUser = userInServerManagementService.loadOrCreateUser(kickLogModel.getMember());
|
||||
AUserInAServer kickingUser = userInServerManagementService.loadOrCreateUser(kickingMember);
|
||||
return infractionService.createInfractionWithNotification(kickedUser, infractionPoints, KICK_INFRACTION_TYPE, reason, kickingUser, logMessage).thenApply(Infraction::getId);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Message> sendKickLog(KickLogModel kickLogModel) {
|
||||
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel, kickLogModel.getGuild().getIdLong());
|
||||
log.debug("Sending kick log message in guild {}.", kickLogModel.getGuild().getIdLong());
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getGuild().getIdLong());
|
||||
@Transactional
|
||||
public CompletableFuture<Long> storeInfraction(ServerUser member, ServerUser kickingMember, String reason, Message logMessage, Long serverId) {
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(ModerationFeatureConfig.KICK_INFRACTION_POINTS, serverId);
|
||||
AUserInAServer kickedUser = userInServerManagementService.loadOrCreateUser(member);
|
||||
AUserInAServer kickingUser = userInServerManagementService.loadOrCreateUser(kickingMember);
|
||||
return infractionService.createInfractionWithNotification(kickedUser, infractionPoints, KICK_INFRACTION_TYPE, reason, kickingUser, logMessage).thenApply(Infraction::getId);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Message> sendKickLog(Member kickedMember, Member kickingMember, String reason, Long serverId) {
|
||||
KickLogModel kickLogModel = KickLogModel
|
||||
.builder()
|
||||
.kickedMember(MemberDisplay.fromMember(kickedMember))
|
||||
.kickingMember(MemberDisplay.fromMember(kickingMember))
|
||||
.reason(reason)
|
||||
.build();
|
||||
return sendKicklog(serverId, kickLogModel);
|
||||
}
|
||||
|
||||
private CompletableFuture<Message> sendKickLog(ServerUser kickedMember, ServerUser kickingMember, String reason, Long serverId) {
|
||||
KickLogModel kickLogModel = KickLogModel
|
||||
.builder()
|
||||
.kickedMember(MemberDisplay.fromServerUser(kickedMember))
|
||||
.kickingMember(MemberDisplay.fromServerUser(kickingMember))
|
||||
.reason(reason)
|
||||
.build();
|
||||
return sendKicklog(serverId, kickLogModel);
|
||||
}
|
||||
|
||||
private CompletableFuture<Message> sendKicklog(Long serverId, KickLogModel kickLogModel) {
|
||||
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel, serverId);
|
||||
log.debug("Sending kick log message in guild {}.", serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures).thenApply(unused -> messageFutures.get(0).join());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ModerationActionPayloadModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ModerationActionServiceBean implements ModerationActionService {
|
||||
|
||||
public static final String WARN_ACTION = "warn";
|
||||
public static final String MUTE_ACTION = "mute";
|
||||
public static final String KICK_ACTION = "kick";
|
||||
public static final String BAN_ACTION = "ban";
|
||||
|
||||
public static final String MODERATION_ACTION_ORIGIN = "moderationAction";
|
||||
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadService componentPayloadService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public List<ModerationActionButton> getModerationActionButtons(ServerUser serverUser) {
|
||||
AServer server = serverManagementService.loadServer(serverUser.getServerId());
|
||||
boolean mutingEnabled = featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.MUTING, serverUser.getServerId());
|
||||
boolean moderationEnabled = featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.MODERATION, serverUser.getServerId());
|
||||
boolean warningsEnabled = featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.WARNING, serverUser.getServerId());
|
||||
List<ModerationActionButton> buttons = new ArrayList<>();
|
||||
if(warningsEnabled) {
|
||||
String warnButtonId = componentService.generateComponentId();
|
||||
ModerationActionPayloadModel warnPayload = ModerationActionPayloadModel.forAction(WARN_ACTION, serverUser);
|
||||
componentPayloadService.createButtonPayload(warnButtonId, warnPayload, MODERATION_ACTION_ORIGIN, server);
|
||||
ModerationActionButton warnAction = ModerationActionButton
|
||||
.builder()
|
||||
.componentId(warnButtonId)
|
||||
.action(WARN_ACTION)
|
||||
.build();
|
||||
buttons.add(warnAction);
|
||||
}
|
||||
if(mutingEnabled) {
|
||||
String muteButtonId = componentService.generateComponentId();
|
||||
ModerationActionPayloadModel mutePayload = ModerationActionPayloadModel.forAction(MUTE_ACTION, serverUser);
|
||||
componentPayloadService.createButtonPayload(muteButtonId, mutePayload, MODERATION_ACTION_ORIGIN, server);
|
||||
ModerationActionButton muteAction = ModerationActionButton
|
||||
.builder()
|
||||
.componentId(muteButtonId)
|
||||
.action(MUTE_ACTION)
|
||||
.build();
|
||||
buttons.add(muteAction);
|
||||
}
|
||||
if(moderationEnabled) {
|
||||
String kickButtonId = componentService.generateComponentId();
|
||||
String banButtonId = componentService.generateComponentId();
|
||||
ModerationActionPayloadModel kickPayload = ModerationActionPayloadModel.forAction(KICK_ACTION, serverUser);
|
||||
ModerationActionPayloadModel banPayload = ModerationActionPayloadModel.forAction(BAN_ACTION, serverUser);
|
||||
componentPayloadService.createButtonPayload(kickButtonId, kickPayload, MODERATION_ACTION_ORIGIN, server);
|
||||
componentPayloadService.createButtonPayload(banButtonId, banPayload, MODERATION_ACTION_ORIGIN, server);
|
||||
ModerationActionButton kickAction = ModerationActionButton
|
||||
.builder()
|
||||
.componentId(kickButtonId)
|
||||
.action(KICK_ACTION)
|
||||
.build();
|
||||
buttons.add(kickAction);
|
||||
ModerationActionButton banAction = ModerationActionButton
|
||||
.builder()
|
||||
.componentId(banButtonId)
|
||||
.action(BAN_ACTION)
|
||||
.build();
|
||||
buttons.add(banAction);
|
||||
}
|
||||
log.info("Attaching {} buttons to moderation action for user {} in server {}.", buttons.size(), serverUser.getUserId(), serverUser.getServerId());
|
||||
return buttons;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -17,9 +18,9 @@ import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefiniti
|
||||
import dev.sheldan.abstracto.moderation.config.feature.MutingFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
||||
import dev.sheldan.abstracto.moderation.model.MuteResult;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteListenerModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteNotification;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.UnMuteLog;
|
||||
@@ -28,9 +29,7 @@ import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -87,9 +86,6 @@ public class MuteServiceBean implements MuteService {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@@ -104,68 +100,39 @@ public class MuteServiceBean implements MuteService {
|
||||
public static final String MUTE_COUNTER_KEY = "MUTES";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteMember(Member memberToMute, String reason, Instant unMuteDate, Long channelId) {
|
||||
FullUserInServer mutedUser = FullUserInServer
|
||||
public CompletableFuture<MuteResult> muteUserInServer(Guild guild, ServerUser userBeingMuted, String reason, Duration duration) {
|
||||
Long serverId = guild.getIdLong();
|
||||
Instant targetDate = Instant.now().plus(duration);
|
||||
MuteNotification muteNotificationModel = MuteNotification
|
||||
.builder()
|
||||
.aUserInAServer(userInServerManagementService.loadOrCreateUser(memberToMute))
|
||||
.member(memberToMute)
|
||||
.build();
|
||||
return muteUserInServer(mutedUser, reason, unMuteDate, channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteUserInServer(FullUserInServer userBeingMuted, String reason, Instant unMuteDate, Long channelId) {
|
||||
Member memberBeingMuted = userBeingMuted.getMember();
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
futures.add(memberService.timeoutUser(userBeingMuted.getMember(), unMuteDate));
|
||||
Guild guild = memberBeingMuted.getGuild();
|
||||
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
|
||||
futures.add(guild.kickVoiceMember(memberBeingMuted).submit());
|
||||
}
|
||||
MuteNotification muteNotification = MuteNotification
|
||||
.builder()
|
||||
.muteTargetDate(unMuteDate)
|
||||
.muteTargetDate(targetDate)
|
||||
.reason(reason)
|
||||
.serverName(guild.getName())
|
||||
.build();
|
||||
futures.add(sendMuteNotification(memberBeingMuted, muteNotification, channelId));
|
||||
return FutureUtils.toSingleFutureGeneric(futures);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendMuteNotification(Member memberBeingMuted, MuteNotification muteNotification, Long channelId) {
|
||||
MuteResult[] result = {MuteResult.SUCCESSFUL};
|
||||
log.info("Notifying the user about the mute.");
|
||||
CompletableFuture<Void> notificationFuture = new CompletableFuture<>();
|
||||
Long guildId = memberBeingMuted.getGuild().getIdLong();
|
||||
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification, guildId);
|
||||
CompletableFuture<Message> messageCompletableFuture = messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage);
|
||||
messageCompletableFuture.exceptionally(throwable -> {
|
||||
GuildMessageChannel feedBackChannel = channelService.getMessageChannelFromServer(guildId, channelId);
|
||||
channelService.sendTextToChannel(throwable.getMessage(), feedBackChannel).whenComplete((exceptionMessage, innerThrowable) -> {
|
||||
notificationFuture.complete(null);
|
||||
log.info("Successfully notified user {} in server {} about mute.", memberBeingMuted.getId(), memberBeingMuted.getGuild().getId());
|
||||
}).exceptionally(throwable1 -> {
|
||||
notificationFuture.completeExceptionally(throwable1);
|
||||
return null;
|
||||
});
|
||||
return null;
|
||||
});
|
||||
messageCompletableFuture.thenAccept(message1 ->
|
||||
notificationFuture.complete(null)
|
||||
);
|
||||
return notificationFuture;
|
||||
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotificationModel, serverId);
|
||||
return messageService.sendMessageToUser(userBeingMuted, muteNotificationMessage)
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to notify about mute", throwable);
|
||||
result[0] = MuteResult.NOTIFICATION_FAILED;
|
||||
return null;
|
||||
})
|
||||
.thenCompose(unused -> memberService.timeoutMember(guild, userBeingMuted, duration, reason))
|
||||
.thenApply(message -> result[0]);
|
||||
}
|
||||
|
||||
private void createMuteObject(MuteContext muteContext, String triggerKey, Long infractionId) {
|
||||
AChannel channel = channelManagementService.loadChannel(muteContext.getChannelId());
|
||||
private void createMuteObject(ServerUser userToMute, ServerUser mutingUser, String reason, Instant targetDate, Long muteId,
|
||||
String triggerKey, Long infractionId, ServerChannelMessage serverChannelMessage) {
|
||||
AChannel channel = channelManagementService.loadChannel(serverChannelMessage.getChannelId());
|
||||
AServerAChannelMessage origin = AServerAChannelMessage
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.server(channel.getServer())
|
||||
.build();
|
||||
AUserInAServer userInServerBeingMuted = userInServerManagementService.loadOrCreateUser(muteContext.getMutedUser());
|
||||
AUserInAServer userInServerMuting = userInServerManagementService.loadOrCreateUser(muteContext.getMutingUser());
|
||||
muteManagementService.createMute(userInServerBeingMuted, userInServerMuting, muteContext.getReason(), muteContext.getMuteTargetDate(), origin, triggerKey, muteContext.getMuteId(), infractionId);
|
||||
AUserInAServer userInServerBeingMuted = userInServerManagementService.loadOrCreateUser(userToMute);
|
||||
AUserInAServer userInServerMuting = userInServerManagementService.loadOrCreateUser(mutingUser);
|
||||
muteManagementService.createMute(userInServerBeingMuted, userInServerMuting, reason, targetDate, origin, triggerKey, muteId, infractionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,27 +167,30 @@ public class MuteServiceBean implements MuteService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteMemberWithLog(MuteContext context) {
|
||||
log.debug("Muting member {} in server {}.", context.getMutedUser().getId(), context.getMutedUser().getGuild().getId());
|
||||
AServer server = serverManagementService.loadOrCreate(context.getMutedUser().getGuild().getIdLong());
|
||||
Long nextCounterValue = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
|
||||
context.setMuteId(nextCounterValue);
|
||||
return muteMember(context.getMutedUser(), context.getReason(), context.getMuteTargetDate(), context.getChannelId())
|
||||
.thenCompose(unused -> self.sendMuteLog(context))
|
||||
.thenCompose(logMessage -> self.evaluateAndStoreInfraction(context, logMessage))
|
||||
.thenAccept(infractionId -> self.persistMute(context, infractionId));
|
||||
public CompletableFuture<MuteResult> muteMemberWithLog(ServerUser userToMute, ServerUser mutingUser, String reason, Duration duration, Guild guild, ServerChannelMessage origin) {
|
||||
Long serverId = userToMute.getServerId();
|
||||
Instant targetDate = Instant.now().plus(duration);
|
||||
log.debug("Muting member {} in server {}.", userToMute.getUserId(), serverId);
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
Long muteId = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
|
||||
CompletableFuture<MuteResult> result = muteUserInServer(guild, userToMute, reason, duration);
|
||||
return result
|
||||
.thenCompose(unused -> self.sendMuteLog(userToMute, mutingUser, duration, reason))
|
||||
.thenCompose(logMessage -> self.evaluateAndStoreInfraction(userToMute, mutingUser, reason, targetDate, logMessage))
|
||||
.thenAccept(infractionId -> self.persistMute(userToMute, mutingUser, targetDate, muteId, reason, infractionId, origin))
|
||||
.thenApply(unused -> result.join());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(MuteContext context, Message logMessage) {
|
||||
Guild guild = context.getMutedUser().getGuild();
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, guild.getIdLong())) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(MutingFeatureConfig.MUTE_INFRACTION_POINTS, guild.getIdLong());
|
||||
AUserInAServer mutedUser = userInServerManagementService.loadOrCreateUser(context.getMutedUser());
|
||||
AUserInAServer mutingUser = userInServerManagementService.loadOrCreateUser(context.getMutingUser());
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(ServerUser userToMute, ServerUser mutingUser, String reason, Instant targetDate, Message logMessage) {
|
||||
Long serverId = userToMute.getServerId();
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(MutingFeatureConfig.MUTE_INFRACTION_POINTS, serverId);
|
||||
AUserInAServer mutedUserInAServer = userInServerManagementService.loadOrCreateUser(userToMute);
|
||||
AUserInAServer mutingUserInAServer = userInServerManagementService.loadOrCreateUser(mutingUser);
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put(INFRACTION_PARAMETER_DURATION_KEY, templateService.renderDuration(Duration.between(Instant.now(), context.getMuteTargetDate()), guild.getIdLong()));
|
||||
return infractionService.createInfractionWithNotification(mutedUser, infractionPoints, MUTE_INFRACTION_TYPE, context.getReason(), mutingUser, parameters, logMessage)
|
||||
parameters.put(INFRACTION_PARAMETER_DURATION_KEY, templateService.renderDuration(Duration.between(Instant.now(), targetDate), serverId));
|
||||
return infractionService.createInfractionWithNotification(mutedUserInAServer, infractionPoints, MUTE_INFRACTION_TYPE, reason, mutingUserInAServer, parameters, logMessage)
|
||||
.thenApply(Infraction::getId);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
@@ -228,26 +198,28 @@ public class MuteServiceBean implements MuteService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistMute(MuteContext context, Long infractionId) {
|
||||
completelyUnMuteMember(context.getMutedUser());
|
||||
String triggerKey = startUnMuteJobFor(context.getMuteTargetDate(), context.getMuteId(), context.getMutedUser().getGuild().getIdLong());
|
||||
createMuteObject(context, triggerKey, infractionId);
|
||||
public void persistMute(ServerUser userToMute, ServerUser mutingUser, Instant targetDate, Long muteId, String reason, Long infractionId, ServerChannelMessage origin) {
|
||||
completelyUnMuteMember(userToMute);
|
||||
String triggerKey = startUnMuteJobFor(targetDate, muteId, userToMute.getServerId());
|
||||
createMuteObject(userToMute, mutingUser, reason, targetDate, muteId, triggerKey, infractionId, origin);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Message> sendMuteLog(MuteContext muteLogModel) {
|
||||
public CompletableFuture<Message> sendMuteLog(ServerUser userBeingMuted, ServerUser mutingUser, Duration duration, String reason) {
|
||||
Instant targetDate = Instant.now().plus(duration);
|
||||
MuteListenerModel model = MuteListenerModel
|
||||
.builder()
|
||||
.mutedUser(muteLogModel.getMutedUser())
|
||||
.mutingUser(muteLogModel.getMutingUser())
|
||||
.channelId(muteLogModel.getChannelId())
|
||||
.mutedUser(MemberDisplay.fromServerUser(userBeingMuted))
|
||||
.mutingUser(MemberDisplay.fromServerUser(mutingUser))
|
||||
.oldMuteTargetDate(null)
|
||||
.muteTargetDate(muteLogModel.getMuteTargetDate())
|
||||
.reason(muteLogModel.getReason())
|
||||
.duration(duration)
|
||||
.muteTargetDate(targetDate)
|
||||
.reason(reason)
|
||||
.build();
|
||||
log.debug("Sending mute log to the mute post target.");
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, muteLogModel.getMutedUser().getIdLong());
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getMutedUser().getGuild().getIdLong());
|
||||
Long serverId = userBeingMuted.getServerId();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, serverId);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenApply(unused -> futures.get(0).join());
|
||||
}
|
||||
|
||||
@@ -268,45 +240,36 @@ public class MuteServiceBean implements MuteService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> unMuteUser(AUserInAServer userToUnmute, Member unMutingMember) {
|
||||
boolean muteActive = muteManagementService.hasActiveMute(userToUnmute);
|
||||
public CompletableFuture<Void> unMuteUser(ServerUser userToUnmute, ServerUser unMutingUser, Guild guild) {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(userToUnmute);
|
||||
boolean muteActive = muteManagementService.hasActiveMute(aUserInAServer);
|
||||
if(!muteActive) {
|
||||
CompletableFuture<Member> unMutedMemberFuture = memberService.retrieveMemberInServer(ServerUser.fromAUserInAServer(userToUnmute));
|
||||
return unMutedMemberFuture
|
||||
.thenCompose(member -> memberService.removeTimeout(member))
|
||||
.thenCompose(unused -> self.sendUnmuteLog(null, unMutingMember.getGuild(), unMutedMemberFuture.join(), unMutingMember));
|
||||
return memberService.removeTimeout(guild, userToUnmute, null)
|
||||
.thenCompose(unused -> self.sendUnmuteLog(null, guild, userToUnmute, unMutingUser));
|
||||
} else {
|
||||
Mute mute = muteManagementService.getAMuteOf(userToUnmute);
|
||||
return endMute(mute);
|
||||
Mute mute = muteManagementService.getAMuteOf(aUserInAServer);
|
||||
return endMute(mute, guild);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> endMute(Mute mute) {
|
||||
public CompletableFuture<Void> endMute(Mute mute, Guild guild) {
|
||||
if(mute.getMuteEnded()) {
|
||||
log.info("Mute {} in server {} has already ended. Not unmuting.", mute.getMuteId().getId(), mute.getMuteId().getServerId());
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
Long muteId = mute.getMuteId().getId();
|
||||
Guild guild = guildService.getGuildById(mute.getMuteId().getServerId());
|
||||
AServer mutingServer = mute.getServer();
|
||||
ServerUser mutedUser = ServerUser.fromAUserInAServer(mute.getMutedUser());
|
||||
ServerUser mutingUser = ServerUser.fromAUserInAServer(mute.getMutedUser());
|
||||
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
|
||||
CompletableFuture<Member> mutedMemberFuture = memberService.getMemberInServerAsync(mute.getMutedUser());
|
||||
CompletableFuture<Member> mutingMemberFuture = memberService.getMemberInServerAsync(mute.getMutingUser());
|
||||
return CompletableFuture.allOf(mutedMemberFuture, mutingMemberFuture)
|
||||
.thenAccept(member -> memberService.removeTimeout(mutedMemberFuture.join()))
|
||||
.thenCompose(unused -> self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture));
|
||||
return memberService.removeTimeout(guild, mutedUser, null)
|
||||
.thenCompose(unused -> self.sendUnmuteLog(muteId, guild, mutedUser, mutingUser));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, CompletableFuture<Member> mutingMemberFuture, CompletableFuture<Member> mutedMemberFuture) {
|
||||
Member mutingMember = !mutingMemberFuture.isCompletedExceptionally() ? mutingMemberFuture.join() : null;
|
||||
Member mutedMember = !mutedMemberFuture.isCompletedExceptionally() ? mutedMemberFuture.join() : null;
|
||||
return sendUnmuteLog(muteId, guild, mutedMember, mutingMember);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, Member mutedMember, Member mutingMember) {
|
||||
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, ServerUser unMutedMember, ServerUser mutingMember) {
|
||||
Mute mute = null;
|
||||
if(muteId != null) {
|
||||
mute = muteManagementService.findMute(muteId, guild.getIdLong());
|
||||
@@ -315,9 +278,8 @@ public class MuteServiceBean implements MuteService {
|
||||
UnMuteLog unMuteLog = UnMuteLog
|
||||
.builder()
|
||||
.mute(mute)
|
||||
.mutingUser(mutingMember)
|
||||
.unMutedUser(mutedMember)
|
||||
.guild(guild)
|
||||
.mutingUser(MemberDisplay.fromServerUser(mutingMember))
|
||||
.unMutedUser(MemberDisplay.fromServerUser(unMutedMember))
|
||||
.build();
|
||||
CompletableFuture<Void> notificationFuture = sendUnMuteLogMessage(unMuteLog, mutingServer);
|
||||
return CompletableFuture.allOf(notificationFuture).thenAccept(aVoid -> {
|
||||
@@ -341,7 +303,8 @@ public class MuteServiceBean implements MuteService {
|
||||
log.info("UnMuting the mute {} in server {}", muteId, serverId);
|
||||
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
|
||||
if(muteOptional.isPresent()) {
|
||||
return endMute(muteOptional.get());
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
return endMute(muteOptional.get(), guild);
|
||||
} else {
|
||||
throw new NoMuteFoundException();
|
||||
}
|
||||
@@ -359,8 +322,8 @@ public class MuteServiceBean implements MuteService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completelyUnMuteMember(Member member) {
|
||||
completelyUnMuteUser(userInServerManagementService.loadOrCreateUser(member));
|
||||
public void completelyUnMuteMember(ServerUser serverUser) {
|
||||
completelyUnMuteUser(userInServerManagementService.loadOrCreateUser(serverUser));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefiniti
|
||||
import dev.sheldan.abstracto.moderation.config.feature.mode.ReportReactionMode;
|
||||
import dev.sheldan.abstracto.moderation.config.posttarget.ReactionReportPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.listener.manager.ReportMessageCreatedListenerManager;
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
import dev.sheldan.abstracto.moderation.model.database.ModerationUser;
|
||||
import dev.sheldan.abstracto.moderation.model.database.ReactionReport;
|
||||
import dev.sheldan.abstracto.moderation.model.template.listener.ReportReactionNotificationModel;
|
||||
@@ -27,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -68,6 +70,9 @@ public class ReactionReportServiceBean implements ReactionReportService {
|
||||
@Autowired
|
||||
private ReportMessageCreatedListenerManager reportMessageCreatedListenerManager;
|
||||
|
||||
@Autowired
|
||||
private ModerationActionService moderationActionService;
|
||||
|
||||
private static final String REACTION_REPORT_TEMPLATE_KEY = "reactionReport_notification";
|
||||
public static final String REACTION_REPORT_MODAL_ORIGIN = "reportMessageModal";
|
||||
public static final String REACTION_REPORT_RESPONSE_TEMPLATE = "reactionReport_response";
|
||||
@@ -93,11 +98,19 @@ public class ReactionReportServiceBean implements ReactionReportService {
|
||||
return channelService.editFieldValueInMessage(reportTextChannel, report.getReportMessageId(), 0, report.getReportCount().toString())
|
||||
.thenAccept(message -> self.updateModerationUserReportCooldown(reporter));
|
||||
} else {
|
||||
boolean reportActionsEnabled = featureModeService.featureModeActive(ModerationFeatureDefinition.REPORT_REACTIONS, serverId, ReportReactionMode.REPORT_ACTIONS);
|
||||
List<ModerationActionButton> moderationActionComponents = new ArrayList<>();
|
||||
if(reportActionsEnabled) {
|
||||
ServerUser reportedServerUser = ServerUser.fromAUserInAServer(reportedUser);
|
||||
List<ModerationActionButton> moderationActions = moderationActionService.getModerationActionButtons(reportedServerUser);
|
||||
moderationActionComponents.addAll(moderationActions);
|
||||
}
|
||||
ReportReactionNotificationModel model = ReportReactionNotificationModel
|
||||
.builder()
|
||||
.reportCount(1)
|
||||
.context(context)
|
||||
.singularMessage(singularMessage)
|
||||
.moderationActionComponents(moderationActionComponents)
|
||||
.reportedMessage(reportedMessage)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(REACTION_REPORT_TEMPLATE_KEY, model, serverId);
|
||||
|
||||
@@ -6,12 +6,12 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.WarningDecayFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.WarningFeatureConfig;
|
||||
@@ -22,7 +22,7 @@ import dev.sheldan.abstracto.moderation.config.posttarget.WarningPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.listener.manager.WarningCreatedListenerManager;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnContext;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnLogModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnNotification;
|
||||
import dev.sheldan.abstracto.moderation.model.template.job.WarnDecayLogModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.job.WarnDecayWarning;
|
||||
@@ -109,50 +109,31 @@ public class WarnServiceBean implements WarnService {
|
||||
public static final String WARN_DECAY_LOG_TEMPLATE_KEY = "warn_decay_log";
|
||||
public static final String WARN_DECAY_NOTIFICATION_TEMPLATE_KEY = "warn_decay_member_notification";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> notifyAndLogFullUserWarning(WarnContext context) {
|
||||
Long serverId = context.getGuild().getIdLong();
|
||||
Long warningId = counterService.getNextCounterValue(serverId, WARNINGS_COUNTER_KEY);
|
||||
context.setWarnId(warningId);
|
||||
Member warnedMember = context.getWarnedMember();
|
||||
Member warningMember = context.getMember();
|
||||
Guild guild = warnedMember.getGuild();
|
||||
log.info("User {} is warning {} in server {}", warnedMember.getId(), warningMember.getId(), guild.getIdLong());
|
||||
WarnNotification warnNotification = WarnNotification
|
||||
.builder()
|
||||
.reason(context.getReason())
|
||||
.warnId(warningId)
|
||||
.serverName(guild.getName())
|
||||
.build();
|
||||
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification, serverId);
|
||||
return messageService.sendMessageToUser(warnedMember.getUser(), warnNotificationMessage)
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to notify user {} of warning {} in guild {}.", warnedMember.getId(), warningId, serverId);
|
||||
return null;
|
||||
})
|
||||
.thenCompose(message -> self.sendWarningLog(context))
|
||||
.thenCompose(logMessage -> self.evaluateInfraction(context, logMessage))
|
||||
.thenAccept(context::setInfractionId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Message> sendWarningLog(WarnContext context) {
|
||||
MessageToSend message = renderMessageModel(context);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, context.getGuild().getIdLong());
|
||||
public CompletableFuture<Message> sendWarningLog(Guild guild, ServerUser warnedUser, ServerUser warningUser, String reason, ServerChannelMessage serverChannelMessage, Long warningId) {
|
||||
WarnLogModel warnContext = WarnLogModel
|
||||
.builder()
|
||||
.warnedMember(MemberDisplay.fromServerUser(warnedUser))
|
||||
.warningMember(MemberDisplay.fromServerUser(warningUser))
|
||||
.channelMessage(serverChannelMessage)
|
||||
.warnId(warningId)
|
||||
.reason(reason)
|
||||
.build();
|
||||
MessageToSend message = renderMessageModel(warnContext, guild.getIdLong());
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, guild.getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenCompose(unused -> futures.get(0));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Long> evaluateInfraction(WarnContext context, Message logMessage) {
|
||||
Long serverId = context.getGuild().getIdLong();
|
||||
public CompletableFuture<Long> evaluateInfraction(Guild guild, ServerUser warnedUser, ServerUser warningUser, String reason, Message logMessage) {
|
||||
Long serverId = guild.getIdLong();
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(WarningFeatureConfig.WARN_INFRACTION_POINTS, serverId);
|
||||
AServer server = serverManagementService.loadServer(context.getGuild());
|
||||
AUserInAServer warnedUser = userInServerManagementService.loadOrCreateUser(server, context.getWarnedMember().getIdLong());
|
||||
AUserInAServer warningUser = userInServerManagementService.loadOrCreateUser(server, context.getMember().getIdLong());
|
||||
AUserInAServer warnedUserInAServer = userInServerManagementService.loadOrCreateUser(warnedUser);
|
||||
AUserInAServer warningUserInAServer = userInServerManagementService.loadOrCreateUser(warningUser);
|
||||
// both user could create the server object, we need to make sure we have the same reference
|
||||
warnedUser.setServerReference(warningUser.getServerReference());
|
||||
return infractionService.createInfractionWithNotification(warnedUser, infractionPoints, WARN_INFRACTION_TYPE, context.getReason(), warningUser, logMessage)
|
||||
warnedUserInAServer.setServerReference(warningUserInAServer.getServerReference());
|
||||
return infractionService.createInfractionWithNotification(warnedUserInAServer, infractionPoints, WARN_INFRACTION_TYPE, reason, warningUserInAServer, logMessage)
|
||||
.thenApply(Infraction::getId);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
@@ -160,36 +141,40 @@ public class WarnServiceBean implements WarnService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> warnUserWithLog(WarnContext context) {
|
||||
return notifyAndLogFullUserWarning(context)
|
||||
.thenAccept(aVoid -> self.persistWarning(context));
|
||||
public CompletableFuture<Void> warnUserWithLog(Guild guild, ServerUser warnedUser, ServerUser warningUser, String reason, ServerChannelMessage serverChannelMessage) {
|
||||
Long serverId = guild.getIdLong();
|
||||
Long warningId = counterService.getNextCounterValue(serverId, WARNINGS_COUNTER_KEY);
|
||||
log.info("User {} is warning {} in server {}", warningUser.getUserId(), warnedUser.getUserId(), serverId);
|
||||
WarnNotification warnNotification = WarnNotification
|
||||
.builder()
|
||||
.reason(reason)
|
||||
.warnId(warningId)
|
||||
.serverName(guild.getName())
|
||||
.build();
|
||||
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification, serverId);
|
||||
return messageService.sendMessageToUser(warnedUser, warnNotificationMessage)
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to notify user {} of warning {} in guild {}.", warnedUser.getUserId(), warningId, serverId, throwable);
|
||||
return null;
|
||||
})
|
||||
.thenCompose(message -> self.sendWarningLog(guild, warnedUser, warningUser, reason, serverChannelMessage, warningId))
|
||||
.thenCompose(logMessage -> self.evaluateInfraction(guild, warnedUser, warningUser, reason, logMessage))
|
||||
.thenAccept(infractionId -> self.persistWarning(warnedUser, warningUser, reason, serverChannelMessage, infractionId, warningId));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistWarning(WarnContext context) {
|
||||
public void persistWarning(ServerUser warnedUser, ServerUser warningUser, String reason, ServerChannelMessage serverChannelMessage, Long infractionId, Long warningId) {
|
||||
Long serverId = warnedUser.getServerId();
|
||||
log.info("Persisting warning {} in server {} for user {} by user {}.",
|
||||
context.getWarnId(), context.getGuild().getId(), context.getWarnedMember().getId(), context.getMember().getId());
|
||||
AUserInAServer warnedUser = userInServerManagementService.loadOrCreateUser(context.getWarnedMember());
|
||||
AUserInAServer warningUser = userInServerManagementService.loadOrCreateUser(context.getMember());
|
||||
Warning createdWarning = warnManagementService.createWarning(warnedUser, warningUser, context.getReason(), context.getWarnId());
|
||||
if(context.getInfractionId() != null) {
|
||||
Infraction infraction = infractionManagementService.loadInfraction(context.getInfractionId());
|
||||
warningId, serverId, warnedUser.getUserId(), warningUser.getUserId());
|
||||
AUserInAServer warnedUserInAServer = userInServerManagementService.loadOrCreateUser(warnedUser);
|
||||
AUserInAServer warningUserInAServer = userInServerManagementService.loadOrCreateUser(warningUser);
|
||||
Warning createdWarning = warnManagementService.createWarning(warnedUserInAServer, warningUserInAServer, reason, warningId);
|
||||
if(infractionId != null) {
|
||||
Infraction infraction = infractionManagementService.loadInfraction(infractionId);
|
||||
createdWarning.setInfraction(infraction);
|
||||
}
|
||||
ServerUser warnedServerUser = ServerUser.fromAUserInAServer(warnedUser);
|
||||
ServerUser warningServerUser = ServerUser.fromAUserInAServer(warnedUser);
|
||||
ServerChannelMessage commandMessage;
|
||||
if(context.getMessage() != null) {
|
||||
commandMessage = ServerChannelMessage.fromMessage(context.getMessage());
|
||||
} else {
|
||||
commandMessage = ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(context.getGuild().getIdLong())
|
||||
.channelId(context.getChannel().getIdLong())
|
||||
.messageId(SnowflakeUtils.createSnowFlake())
|
||||
.build();
|
||||
}
|
||||
warningCreatedListenerManager.sendWarningCreatedEvent(createdWarning.getWarnId(), warnedServerUser, warningServerUser, context.getReason(), commandMessage);
|
||||
warningCreatedListenerManager.sendWarningCreatedEvent(createdWarning.getWarnId(), warnedUser, warningUser, reason, serverChannelMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,8 +293,8 @@ public class WarnServiceBean implements WarnService {
|
||||
}
|
||||
}
|
||||
|
||||
public MessageToSend renderMessageModel(WarnContext warnContext) {
|
||||
return templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnContext, warnContext.getGuild().getIdLong());
|
||||
public MessageToSend renderMessageModel(WarnLogModel warnContext, Long serverId) {
|
||||
return templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnContext, serverId);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
|
||||
|
||||
@@ -57,6 +57,10 @@ abstracto.featureModes.singularReportReactions.featureName=reportReactions
|
||||
abstracto.featureModes.singularReportReactions.mode=singularReportReactions
|
||||
abstracto.featureModes.singularReportReactions.enabled=false
|
||||
|
||||
abstracto.featureModes.reactionReportActions.featureName=reportReactions
|
||||
abstracto.featureModes.reactionReportActions.mode=reactionReportActions
|
||||
abstracto.featureModes.reactionReportActions.enabled=false
|
||||
|
||||
abstracto.systemConfigs.infractionLvl1.name=infractionLvl1
|
||||
abstracto.systemConfigs.infractionLvl1.longValue=10
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
||||
import dev.sheldan.abstracto.moderation.service.KickServiceBean;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class KickTest {
|
||||
|
||||
@InjectMocks
|
||||
private Kick testUnit;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
|
||||
@Mock
|
||||
private KickServiceBean kickService;
|
||||
|
||||
@Mock
|
||||
private Member memberToKick;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<KickLogModel> logModelArgumentCaptor;
|
||||
|
||||
private static final String REASON = "reason";
|
||||
private static final Long SERVER_ID = 1L;
|
||||
|
||||
@Test
|
||||
public void testKickMemberWithoutReason() {
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToKick));
|
||||
when(memberToKick.getGuild()).thenReturn(parameters.getGuild());
|
||||
when(parameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
|
||||
when(templateService.renderSimpleTemplate(Kick.KICK_DEFAULT_REASON_TEMPLATE, SERVER_ID)).thenReturn(REASON);
|
||||
when(kickService.kickMember(eq(memberToKick), eq(REASON), logModelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
|
||||
Assert.assertEquals(REASON, usedLogModel.getReason());
|
||||
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
|
||||
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getMember());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKickMemberWithReason() {
|
||||
String customReason = "reason2";
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToKick, customReason));
|
||||
when(memberToKick.getGuild()).thenReturn(parameters.getGuild());
|
||||
when(kickService.kickMember(eq(memberToKick), eq(customReason), logModelArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
KickLogModel usedLogModel = logModelArgumentCaptor.getValue();
|
||||
Assert.assertEquals(customReason, usedLogModel.getReason());
|
||||
Assert.assertEquals(memberToKick, usedLogModel.getKickedUser());
|
||||
Assert.assertEquals(parameters.getAuthor(), usedLogModel.getMember());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommand() {
|
||||
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnContext;
|
||||
import dev.sheldan.abstracto.moderation.service.WarnService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class WarnTest {
|
||||
|
||||
@InjectMocks
|
||||
private Warn testUnit;
|
||||
|
||||
@Mock
|
||||
private WarnService warnService;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
private static final String DEFAULT_REASON = "defaultReason";
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<WarnContext> parameterCaptor;
|
||||
|
||||
private static final Long SERVER_ID = 1L;
|
||||
|
||||
@Test
|
||||
public void testExecuteWarnCommandWithReason() {
|
||||
Member warnedMember = Mockito.mock(Member.class);
|
||||
String reason = "reason";
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(warnedMember, reason));
|
||||
when(warnedMember.getGuild()).thenReturn(parameters.getGuild());
|
||||
when(parameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
|
||||
when(templateService.renderSimpleTemplate(Warn.WARN_DEFAULT_REASON_TEMPLATE, SERVER_ID)).thenReturn(DEFAULT_REASON);
|
||||
when(warnService.warnUserWithLog(parameterCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
WarnContext value = parameterCaptor.getValue();
|
||||
Assert.assertEquals(reason, value.getReason());
|
||||
Assert.assertEquals(warnedMember, value.getWarnedMember());
|
||||
Assert.assertEquals(parameters.getAuthor(), value.getMember());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteWarnCommandWithDefaultReason() {
|
||||
Member warnedMember = Mockito.mock(Member.class);
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(warnedMember));
|
||||
when(warnedMember.getGuild()).thenReturn(parameters.getGuild());
|
||||
when(parameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
|
||||
when(templateService.renderSimpleTemplate(Warn.WARN_DEFAULT_REASON_TEMPLATE, SERVER_ID)).thenReturn(DEFAULT_REASON);
|
||||
when(warnService.warnUserWithLog(parameterCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
WarnContext value = parameterCaptor.getValue();
|
||||
Assert.assertEquals(DEFAULT_REASON, value.getReason());
|
||||
Assert.assertEquals(warnedMember, value.getWarnedMember());
|
||||
Assert.assertEquals(parameters.getAuthor(), value.getMember());
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommand() {
|
||||
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.command.mute;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
||||
import dev.sheldan.abstracto.moderation.command.Mute;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MuteTest {
|
||||
|
||||
@InjectMocks
|
||||
private Mute testUnit;
|
||||
|
||||
@Mock
|
||||
private MuteService muteService;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<MuteContext> muteLogArgumentCaptor;
|
||||
|
||||
@Test
|
||||
public void testMuteMember() {
|
||||
Member mutedMember = Mockito.mock(Member.class);
|
||||
String reason = "reason";
|
||||
Duration duration = Duration.ofMinutes(1);
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(mutedMember, duration, reason));
|
||||
when(mutedMember.getGuild()).thenReturn(parameters.getGuild());
|
||||
when(muteService.muteMemberWithLog(muteLogArgumentCaptor.capture())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
MuteContext muteLog = muteLogArgumentCaptor.getValue();
|
||||
Assert.assertEquals(mutedMember, muteLog.getMutedUser());
|
||||
Assert.assertEquals(parameters.getAuthor(), muteLog.getMutingUser());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateCommand() {
|
||||
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -38,6 +38,6 @@ public class ReportReactionFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(ReportReactionMode.SINGULAR_MESSAGE, ReportReactionMode.ANONYMOUS);
|
||||
return Arrays.asList(ReportReactionMode.values());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,6 @@ public class WarningDecayFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(WarnDecayMode.AUTOMATIC_WARN_DECAY_LOG);
|
||||
return Arrays.asList(WarnDecayMode.values());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class WarningFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(WarningMode.WARN_DECAY_LOG);
|
||||
return Arrays.asList(WarningMode.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ReportReactionMode implements FeatureMode {
|
||||
SINGULAR_MESSAGE("singularReportReactions"), ANONYMOUS("anonymousReportReactions");
|
||||
SINGULAR_MESSAGE("singularReportReactions"), ANONYMOUS("anonymousReportReactions"), REPORT_ACTIONS("reactionReportActions");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.model;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ModerationActionButton {
|
||||
private String componentId;
|
||||
private String action;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.model;
|
||||
|
||||
public enum MuteResult {
|
||||
NOTIFICATION_FAILED, SUCCESSFUL
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.moderation.model.interaction;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalPayload;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ModerationActionBanPayload implements ModalPayload {
|
||||
private String modalId;
|
||||
private String reasonInputId;
|
||||
private String durationInputId;
|
||||
private Long serverId;
|
||||
private Long bannedUserId;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.moderation.model.interaction;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalPayload;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ModerationActionKickPayload implements ModalPayload {
|
||||
private String modalId;
|
||||
private String reasonInputId;
|
||||
private Long serverId;
|
||||
private Long kickedUserId;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.moderation.model.interaction;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalPayload;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ModerationActionMutePayload implements ModalPayload {
|
||||
private String modalId;
|
||||
private String reasonInputId;
|
||||
private String durationInputId;
|
||||
private Long serverId;
|
||||
private Long mutedUserId;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.moderation.model.interaction;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.modal.ModalPayload;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ModerationActionWarnPayload implements ModalPayload {
|
||||
private String modalId;
|
||||
private String reasonInputId;
|
||||
private Long serverId;
|
||||
private Long warnedUserId;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@@ -24,11 +23,10 @@ public class BanLog {
|
||||
/**
|
||||
* The member executing the ban
|
||||
*/
|
||||
private Member banningMember;
|
||||
private MemberDisplay banningMember;
|
||||
/**
|
||||
* The user being banned
|
||||
*/
|
||||
private User bannedUser;
|
||||
private Message commandMessage;
|
||||
private UserDisplay bannedUser;
|
||||
private Duration deletionDuration;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
|
||||
/**
|
||||
* Used when rendering the notification when a member was kicked. The template is: "kick_log_embed"
|
||||
@@ -14,15 +12,7 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
@Builder
|
||||
@Setter
|
||||
public class KickLogModel {
|
||||
/**
|
||||
* The reason of the kick
|
||||
*/
|
||||
private String reason;
|
||||
/**
|
||||
* The member being kicked
|
||||
*/
|
||||
private Member kickedUser;
|
||||
private Member member;
|
||||
private Guild guild;
|
||||
private GuildMessageChannel channel;
|
||||
private MemberDisplay kickedMember;
|
||||
private MemberDisplay kickingMember;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -13,27 +14,19 @@ public class MuteListenerModel {
|
||||
/**
|
||||
* The {@link Member} being muted
|
||||
*/
|
||||
private Member mutedUser;
|
||||
private MemberDisplay mutedUser;
|
||||
/**
|
||||
* The {@link Member} executing the mute
|
||||
*/
|
||||
private Member mutingUser;
|
||||
private MemberDisplay mutingUser;
|
||||
/**
|
||||
* The persisted mute object from the database containing the information about the mute
|
||||
*/
|
||||
private Long muteId;
|
||||
private Instant muteTargetDate;
|
||||
private Instant oldMuteTargetDate;
|
||||
private Duration duration;
|
||||
private String reason;
|
||||
private Long channelId;
|
||||
|
||||
/**
|
||||
* The {@link Duration} of the mute between the mute was cast and and the date it should end
|
||||
* @return The {@link Duration} between start and target date
|
||||
*/
|
||||
public Duration getMuteDuration() {
|
||||
return Duration.between(Instant.now(), muteTargetDate);
|
||||
}
|
||||
|
||||
public boolean getMuteEnded() {
|
||||
return oldMuteTargetDate != null && muteTargetDate == null || oldMuteTargetDate == null && muteTargetDate == null;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
|
||||
|
||||
/**
|
||||
* Used when rendering the notification when a member was banned. The template is: "ban_log_embed"
|
||||
@@ -18,10 +16,9 @@ public class UnBanLog {
|
||||
/**
|
||||
* The member executing the unban
|
||||
*/
|
||||
private Member unBanningMember;
|
||||
private MemberDisplay unBanningMember;
|
||||
/**
|
||||
* The user being unbanned
|
||||
*/
|
||||
private User bannedUser;
|
||||
private Message commandMessage;
|
||||
private UserDisplay bannedUser;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.ServerContext;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.utils.MessageUtils;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -8,7 +8,6 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -21,15 +20,15 @@ import java.time.Instant;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UnMuteLog extends ServerContext {
|
||||
public class UnMuteLog {
|
||||
/**
|
||||
* The un-muted Member, is null if the member left the server
|
||||
*/
|
||||
private Member unMutedUser;
|
||||
private MemberDisplay unMutedUser;
|
||||
/**
|
||||
* The user casting the mute, is null if the member left the server
|
||||
*/
|
||||
private Member mutingUser;
|
||||
private MemberDisplay mutingUser;
|
||||
/**
|
||||
* The persisted mute object from the database containing the information about the mute
|
||||
*/
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
|
||||
/**
|
||||
* Used when rendering the notification when a member was warned. The template is: "warn_log_embed"
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@Setter
|
||||
public class WarnContext {
|
||||
/**
|
||||
* The reason why the warn was cast
|
||||
*/
|
||||
private String reason;
|
||||
/**
|
||||
* The {@link Member} being warned
|
||||
*/
|
||||
private Member warnedMember;
|
||||
/**
|
||||
* The persisted {@link Warning} object from the database containing the information about the warning
|
||||
*/
|
||||
private Long warnId;
|
||||
private Long infractionId;
|
||||
private Member member;
|
||||
private Guild guild;
|
||||
private Message message;
|
||||
private GuildMessageChannel channel;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
/**
|
||||
* Used when rendering the notification when a member was warned. The template is: "warn_log_embed"
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@Setter
|
||||
public class WarnLogModel {
|
||||
/**
|
||||
* The reason why warn was cast
|
||||
*/
|
||||
private String reason;
|
||||
/**
|
||||
* The {@link Member} being warned
|
||||
*/
|
||||
private MemberDisplay warnedMember;
|
||||
private Long warnId;
|
||||
private Long infractionId;
|
||||
private MemberDisplay warningMember;
|
||||
private ServerChannelMessage channelMessage;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ModerationActionBanModalModel {
|
||||
private String modalId;
|
||||
private String reasonComponentId;
|
||||
private String durationComponentId;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ModerationActionKickModalModel {
|
||||
private String modalId;
|
||||
private String reasonComponentId;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ModerationActionMuteModalModel {
|
||||
private String modalId;
|
||||
private String reasonComponentId;
|
||||
private String durationComponentId;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class ModerationActionPayloadModel implements ButtonPayload {
|
||||
private String action;
|
||||
private ServerUser user;
|
||||
|
||||
public static ModerationActionPayloadModel forAction(String action, ServerUser user) {
|
||||
return ModerationActionPayloadModel
|
||||
.builder()
|
||||
.user(user)
|
||||
.action(action)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ModerationActionWarnModalModel {
|
||||
private String modalId;
|
||||
private String reasonComponentId;
|
||||
}
|
||||
@@ -2,10 +2,13 @@ package dev.sheldan.abstracto.moderation.model.template.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@@ -15,4 +18,5 @@ public class ReportReactionNotificationModel {
|
||||
private Integer reportCount;
|
||||
private String context;
|
||||
private Boolean singularMessage;
|
||||
private List<ModerationActionButton> moderationActionComponents;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.model.BanResult;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
|
||||
@@ -10,9 +11,9 @@ public interface BanService {
|
||||
String BAN_EFFECT_KEY = "ban";
|
||||
String BAN_INFRACTION_TYPE = "ban";
|
||||
String INFRACTION_PARAMETER_DELETION_DURATION_KEY = "DELETION_DURATION";
|
||||
CompletableFuture<BanResult> banUserWithNotification(User user, String reason, Member banningMember, Duration deletionDuration);
|
||||
CompletableFuture<Void> unBanUserWithNotification(User user, Member unBanningUser);
|
||||
CompletableFuture<Void> banUser(Guild guild, User user, Duration deletionDuration, String reason);
|
||||
CompletableFuture<Void> unbanUser(Guild guild, User user);
|
||||
CompletableFuture<Void> softBanUser(Guild guild, User user, Duration delDays);
|
||||
CompletableFuture<BanResult> banUserWithNotification(ServerUser userToBeBanned, String reason, ServerUser banningUser, Guild guild, Duration deletionDuration);
|
||||
CompletableFuture<Void> unBanUserWithNotification(Long userId, ServerUser unBanningMember, Guild guild);
|
||||
CompletableFuture<Void> banUser(Guild guild, ServerUser userToBeBanned, Duration deletionDuration, String reason);
|
||||
CompletableFuture<Void> unbanUser(Guild guild, Long userId);
|
||||
CompletableFuture<Void> softBanUser(Guild guild, ServerUser user, Duration delDays);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -8,5 +9,6 @@ import java.util.concurrent.CompletableFuture;
|
||||
public interface KickService {
|
||||
String KICK_EFFECT_KEY = "kick";
|
||||
String KICK_INFRACTION_TYPE = "kick";
|
||||
CompletableFuture<Void> kickMember(Member member, String reason, KickLogModel kickLogModel);
|
||||
CompletableFuture<Void> kickMember(Member kickedMember, Member kickingMember, String reason);
|
||||
CompletableFuture<Void> kickMember(Guild guild, ServerUser kickedUser, String reason, ServerUser kickingUser);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.moderation.model.ModerationActionButton;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ModerationActionService {
|
||||
List<ModerationActionButton> getModerationActionButtons(ServerUser serverUser);
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.moderation.model.MuteResult;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -13,14 +15,13 @@ public interface MuteService {
|
||||
String MUTE_EFFECT_KEY = "mute";
|
||||
String MUTE_INFRACTION_TYPE = "mute";
|
||||
String INFRACTION_PARAMETER_DURATION_KEY = "DURATION";
|
||||
CompletableFuture<Void> muteMember(Member memberToMute, String reason, Instant unMuteDate, Long channelId);
|
||||
CompletableFuture<Void> muteUserInServer(FullUserInServer userToMute, String reason, Instant unMuteDate, Long channelId);
|
||||
CompletableFuture<Void> muteMemberWithLog(MuteContext context);
|
||||
CompletableFuture<MuteResult> muteUserInServer(Guild guild, ServerUser userBeingMuted, String reason, Duration duration);
|
||||
CompletableFuture<MuteResult> muteMemberWithLog(ServerUser userToMute, ServerUser mutingUser, String reason, Duration duration, Guild guild, ServerChannelMessage origin);
|
||||
String startUnMuteJobFor(Instant unMuteDate, Long muteId, Long serverId);
|
||||
void cancelUnMuteJob(Mute mute);
|
||||
CompletableFuture<Void> unMuteUser(AUserInAServer userToUnmute, Member memberUnMuting);
|
||||
CompletableFuture<Void> endMute(Mute mute);
|
||||
CompletableFuture<Void> unMuteUser(ServerUser userToUnMute, ServerUser memberUnMuting, Guild guild);
|
||||
CompletableFuture<Void> endMute(Mute mute, Guild guild);
|
||||
CompletableFuture<Void> endMute(Long muteId, Long serverId);
|
||||
void completelyUnMuteUser(AUserInAServer aUserInAServer);
|
||||
void completelyUnMuteMember(Member member);
|
||||
void completelyUnMuteMember(ServerUser serverUser);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.WarnContext;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -11,8 +13,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
public interface WarnService {
|
||||
String WARN_EFFECT_KEY = "warn";
|
||||
String WARN_INFRACTION_TYPE = "warn";
|
||||
CompletableFuture<Void> notifyAndLogFullUserWarning(WarnContext context);
|
||||
CompletableFuture<Void> warnUserWithLog(WarnContext context);
|
||||
CompletableFuture<Void> warnUserWithLog(Guild guild, ServerUser warnedUser, ServerUser warningUser, String reason, ServerChannelMessage serverChannelMessage);
|
||||
void decayWarning(Warning warning, Instant decayDate);
|
||||
CompletableFuture<Void> decayWarningsForServer(AServer server);
|
||||
CompletableFuture<Void> decayAllWarningsForServer(AServer server);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.5.26</version>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
</parent>
|
||||
<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