mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-06-16 23:33:48 +00:00
[AB-52] upgrading to alpha 12
adding anonymous reporting reworking message context commands refactoring interaction packages adding post execution handling for message context commands and modals reworking feature mode response fixing setup using component ids storing infraction parameters, for example mute duration, with every infraction adding infractions for more moderation actions creating general method to format a duration string adding infractions command reworking muting to use built-in functionality of discord enabling chunking of members removing manual unmuting feature mode adding ability to update infractions with a command implemented infraction listeners for ban and warn refactored infraction notifications storing log messages to the infraction for editing said log messages
This commit is contained in:
@@ -5,10 +5,7 @@ import dev.sheldan.abstracto.antiraid.model.MassPingNotificationModel;
|
|||||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
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.MemberDisplay;
|
||||||
import dev.sheldan.abstracto.core.service.ConditionService;
|
import dev.sheldan.abstracto.core.service.*;
|
||||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
|
||||||
import dev.sheldan.abstracto.core.service.SystemCondition;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
@@ -61,19 +58,22 @@ public class MassPingServiceBean implements MassPingService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserInServerManagementService userInServerManagementService;
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberService memberService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> processMessage(Message message) {
|
public CompletableFuture<Void> processMessage(Message message) {
|
||||||
if(message.getMentionedMembers().size() > maxAllowedMentions) {
|
if(message.getMentions().getUsers().size() > maxAllowedMentions) {
|
||||||
Integer level = configService.getLongValueOrConfigDefault(MassPingService.MAX_AFFECTED_LEVEL_KEY, message.getGuild().getIdLong()).intValue();
|
Integer level = configService.getLongValueOrConfigDefault(MassPingService.MAX_AFFECTED_LEVEL_KEY, message.getGuild().getIdLong()).intValue();
|
||||||
boolean allowed = allowedToMassMention(message, level);
|
boolean allowed = allowedToMassMention(message, level);
|
||||||
if(!allowed) {
|
if(!allowed) {
|
||||||
return muteService.muteMemberWithoutContext(message.getMember())
|
return memberService.timeoutUserMaxDuration(message.getMember())
|
||||||
.thenAccept(unused -> self.sendMassPingMuteNotification(message))
|
.thenAccept(unused -> self.sendMassPingMuteNotification(message))
|
||||||
.thenAccept(unused -> log.info("Muted member {} in server {} because of too many member mentions. (> {}).",
|
.thenAccept(unused -> log.info("Muted member {} in server {} because of too many member mentions. (> {}).",
|
||||||
message.getMember().getIdLong(), message.getGuild().getIdLong(), maxAllowedMentions));
|
message.getAuthor().getIdLong(), message.getGuild().getIdLong(), maxAllowedMentions));
|
||||||
} else {
|
} else {
|
||||||
log.info("User {} in server {} is allowed to mass mention, because of level (or lack of level configuration).",
|
log.info("User {} in server {} is allowed to mass mention, because of level (or lack of level configuration).",
|
||||||
message.getMember().getIdLong(), message.getGuild().getIdLong());
|
message.getAuthor().getIdLong(), message.getGuild().getIdLong());
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -103,7 +103,7 @@ public class MassPingServiceBean implements MassPingService {
|
|||||||
MassPingNotificationModel model = MassPingNotificationModel
|
MassPingNotificationModel model = MassPingNotificationModel
|
||||||
.builder()
|
.builder()
|
||||||
.messageLink(message.getJumpUrl())
|
.messageLink(message.getJumpUrl())
|
||||||
.mentionCount(message.getMentionedMembers().size())
|
.mentionCount(message.getMentions().getUsers().size())
|
||||||
.messageContent(message.getContentRaw())
|
.messageContent(message.getContentRaw())
|
||||||
.memberDisplay(MemberDisplay.fromMember(member))
|
.memberDisplay(MemberDisplay.fromMember(member))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUser
|
|||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||||
import dev.sheldan.abstracto.core.service.RoleService;
|
import dev.sheldan.abstracto.core.service.RoleService;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package dev.sheldan.abstracto.assignableroles.model;
|
package dev.sheldan.abstracto.assignableroles.model;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.template.button.ButtonPayload;
|
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import dev.sheldan.abstracto.assignableroles.service.management.*;
|
|||||||
import dev.sheldan.abstracto.core.command.exception.CommandParameterKeyValueWrongTypeException;
|
import dev.sheldan.abstracto.core.command.exception.CommandParameterKeyValueWrongTypeException;
|
||||||
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
|
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
|
||||||
import dev.sheldan.abstracto.core.exception.EmoteNotUsableException;
|
import dev.sheldan.abstracto.core.exception.EmoteNotUsableException;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentPayloadService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||||
import dev.sheldan.abstracto.core.models.FullEmote;
|
import dev.sheldan.abstracto.core.models.FullEmote;
|
||||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
|
import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.config.*;
|
|||||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package dev.sheldan.abstracto.linkembed.listener;
|
package dev.sheldan.abstracto.linkembed.listener;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||||
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
|
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.MessageService;
|
import dev.sheldan.abstracto.core.service.MessageService;
|
||||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.linkembed.exception.LinkEmbedRemovalNotAllowedException;
|
import dev.sheldan.abstracto.linkembed.exception.LinkEmbedRemovalNotAllowedException;
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package dev.sheldan.abstracto.linkembed.listener.interaction;
|
|||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.MessageContextConfig;
|
import dev.sheldan.abstracto.core.interaction.MessageContextConfig;
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.async.MessageContextCommandListener;
|
import dev.sheldan.abstracto.core.interaction.context.message.listener.MessageContextCommandListener;
|
||||||
import dev.sheldan.abstracto.core.models.GuildMemberMessageChannel;
|
import dev.sheldan.abstracto.core.models.GuildMemberMessageChannel;
|
||||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.listener.interaction.MessageContextInteractionModel;
|
import dev.sheldan.abstracto.core.models.listener.interaction.MessageContextInteractionModel;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.context.ContextCommandService;
|
||||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||||
@@ -15,7 +16,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.Command;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -36,6 +36,9 @@ public class MessageEmbedContextCommandListener implements MessageContextCommand
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MessageEmbedContextCommandListener self;
|
private MessageEmbedContextCommandListener self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ContextCommandService contextCommandService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultListenerResult execute(MessageContextInteractionModel model) {
|
public DefaultListenerResult execute(MessageContextInteractionModel model) {
|
||||||
MessageContextInteractionEvent event = model.getEvent();
|
MessageContextInteractionEvent event = model.getEvent();
|
||||||
@@ -70,14 +73,14 @@ public class MessageEmbedContextCommandListener implements MessageContextCommand
|
|||||||
public MessageContextConfig getConfig() {
|
public MessageContextConfig getConfig() {
|
||||||
return MessageContextConfig
|
return MessageContextConfig
|
||||||
.builder()
|
.builder()
|
||||||
.name("Embed message")
|
.isTemplated(true)
|
||||||
|
.name("embed_message")
|
||||||
|
.templateKey("message_embed_message_context_menu_label")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean handlesEvent(MessageContextInteractionModel model) {
|
public Boolean handlesEvent(MessageContextInteractionModel model) {
|
||||||
return model.getEvent().getName().equals(getConfig().getName())
|
return contextCommandService.matchesGuildContextName(model, getConfig(), model.getServerId());
|
||||||
&& model.getEvent().isFromGuild()
|
|
||||||
&& model.getEvent().getCommandType().equals(Command.Type.MESSAGE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package dev.sheldan.abstracto.linkembed.service;
|
package dev.sheldan.abstracto.linkembed.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.models.GuildMemberMessageChannel;
|
import dev.sheldan.abstracto.core.models.GuildMemberMessageChannel;
|
||||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.models.template.button.ButtonConfigModel;
|
import dev.sheldan.abstracto.core.interaction.button.ButtonConfigModel;
|
||||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureMode;
|
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureMode;
|
||||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbedDeleteButtonPayload;
|
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbedDeleteButtonPayload;
|
||||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbeddedModel;
|
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbeddedModel;
|
||||||
import dev.sheldan.abstracto.core.service.*;
|
import dev.sheldan.abstracto.core.service.*;
|
||||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
@@ -26,7 +26,6 @@ import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManage
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.interactions.commands.CommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.CommandInteraction;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -287,7 +286,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
|||||||
buttonConfigModel.setOrigin(MESSAGE_EMBED_DELETE_ORIGIN);
|
buttonConfigModel.setOrigin(MESSAGE_EMBED_DELETE_ORIGIN);
|
||||||
buttonConfigModel.setPayloadType(MessageEmbedDeleteButtonPayload.class);
|
buttonConfigModel.setPayloadType(MessageEmbedDeleteButtonPayload.class);
|
||||||
AServer server = serverManagementService.loadServer(serverId);
|
AServer server = serverManagementService.loadServer(serverId);
|
||||||
componentPayloadManagementService.createPayload(buttonConfigModel, server);
|
componentPayloadManagementService.createButtonPayload(buttonConfigModel, server);
|
||||||
self.loadUserAndPersistMessage(cachedMessage, embeddingUserInServerId, createdMessage, messageEmbeddedModel.getButtonConfigModel().getButtonId());
|
self.loadUserAndPersistMessage(cachedMessage, embeddingUserInServerId, createdMessage, messageEmbeddedModel.getButtonConfigModel().getButtonId());
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
} else {
|
} else {
|
||||||
@@ -358,7 +357,7 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
|||||||
|
|
||||||
private Boolean shouldMentionReferencedAuthor(Message message) {
|
private Boolean shouldMentionReferencedAuthor(Message message) {
|
||||||
if(message.getReferencedMessage() != null) {
|
if(message.getReferencedMessage() != null) {
|
||||||
return message.getMentionedUsers().contains(message.getReferencedMessage().getAuthor());
|
return message.getMentions().getMentions(Message.MentionType.USER).contains(message.getReferencedMessage().getAuthor());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<property name="linkEmbedsFeature" value="(SELECT id FROM feature WHERE key = 'linkEmbeds')"/>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="embed_message_context_command">
|
||||||
|
<insert tableName="context_command">
|
||||||
|
<column name="name" value="embed_message"/>
|
||||||
|
<column name="type" value="MESSAGE"/>
|
||||||
|
<column name="feature_id" valueComputed="${linkEmbedsFeature}"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<include file="context_command.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -10,4 +10,5 @@
|
|||||||
<include file="1.2.8-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.2.8-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.3.0/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.3.0/collection.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package dev.sheldan.abstracto.linkembed.model.template;
|
package dev.sheldan.abstracto.linkembed.model.template;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.template.button.ButtonPayload;
|
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.linkembed.model.template;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||||
import dev.sheldan.abstracto.core.models.template.button.ButtonConfigModel;
|
import dev.sheldan.abstracto.core.interaction.button.ButtonConfigModel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
|||||||
import dev.sheldan.abstracto.core.command.config.*;
|
import dev.sheldan.abstracto.core.command.config.*;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||||
@@ -29,6 +30,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static dev.sheldan.abstracto.moderation.model.BanResult.NOTIFICATION_FAILED;
|
||||||
import static dev.sheldan.abstracto.moderation.service.BanService.BAN_EFFECT_KEY;
|
import static dev.sheldan.abstracto.moderation.service.BanService.BAN_EFFECT_KEY;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -69,10 +71,14 @@ public class Ban extends AbstractConditionableCommand {
|
|||||||
Member banningMember = commandContext.getAuthor();
|
Member banningMember = commandContext.getAuthor();
|
||||||
return banService.banUserWithNotification(user, reason, commandContext.getAuthor(), 0)
|
return banService.banUserWithNotification(user, reason, commandContext.getAuthor(), 0)
|
||||||
.thenCompose(banResult -> {
|
.thenCompose(banResult -> {
|
||||||
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, guild.getIdLong());
|
if(banResult == NOTIFICATION_FAILED) {
|
||||||
return channelService.sendTextToChannel(errorNotification, message.getChannel())
|
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, guild.getIdLong());
|
||||||
.thenAccept(message1 -> log.info("Notified about not being able to send ban notification in server {} and channel {} from user {}."
|
return channelService.sendTextToChannel(errorNotification, message.getChannel())
|
||||||
, guild, message.getChannel().getIdLong(), banningMember.getIdLong()));
|
.thenAccept(message1 -> log.info("Notified about not being able to send ban notification in server {} and channel {} from user {}."
|
||||||
|
, guild, message.getChannel().getIdLong(), banningMember.getIdLong()));
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||||
}
|
}
|
||||||
@@ -83,14 +89,28 @@ public class Ban extends AbstractConditionableCommand {
|
|||||||
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
||||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||||
return banService.banUserWithNotification(member.getUser(), reason, event.getMember(), 0)
|
return banService.banUserWithNotification(member.getUser(), reason, event.getMember(), 0)
|
||||||
.thenCompose(banResult -> interactionService.replyEmbed(BAN_RESPONSE, event))
|
.thenCompose(banResult -> {
|
||||||
|
if(banResult == NOTIFICATION_FAILED) {
|
||||||
|
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, event.getGuild().getIdLong());
|
||||||
|
return interactionService.replyString(errorNotification, event);
|
||||||
|
} else {
|
||||||
|
return interactionService.replyEmbed(BAN_RESPONSE, event);
|
||||||
|
}
|
||||||
|
})
|
||||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||||
} else {
|
} else {
|
||||||
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
||||||
Long userId = Long.parseLong(userIdStr);
|
Long userId = Long.parseLong(userIdStr);
|
||||||
return userService.retrieveUserForId(userId)
|
return userService.retrieveUserForId(userId)
|
||||||
.thenCompose(user -> banService.banUserWithNotification(user, reason, event.getMember(), 0))
|
.thenCompose(user -> banService.banUserWithNotification(user, reason, event.getMember(), 0))
|
||||||
.thenCompose(banResult -> interactionService.replyEmbed(BAN_RESPONSE, event))
|
.thenCompose(banResult -> {
|
||||||
|
if(banResult == NOTIFICATION_FAILED) {
|
||||||
|
String errorNotification = templateService.renderSimpleTemplate(BAN_NOTIFICATION_NOT_POSSIBLE, event.getGuild().getIdLong());
|
||||||
|
return interactionService.replyString(errorNotification, event);
|
||||||
|
} else {
|
||||||
|
return interactionService.replyEmbed(BAN_RESPONSE, event);
|
||||||
|
}
|
||||||
|
})
|
||||||
.thenApply(banResult -> CommandResult.fromSuccess());
|
.thenApply(banResult -> CommandResult.fromSuccess());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
@@ -64,7 +64,7 @@ public class DecayAllWarnings extends AbstractConditionableCommand {
|
|||||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
.builder()
|
.builder()
|
||||||
.enabled(true)
|
.enabled(true)
|
||||||
.rootCommandName(ModerationSlashCommandNames.MUTE)
|
.rootCommandName(ModerationSlashCommandNames.WARN_DECAY)
|
||||||
.commandName(DECAY_ALL_WARNINGS_COMMAND)
|
.commandName(DECAY_ALL_WARNINGS_COMMAND)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.config.*;
|
|||||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.config.*;
|
|||||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.command;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
|
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.service.InfractionService;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class EditInfraction extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
private static final String EDIT_INFRACTION_COMMAND = "editInfraction";
|
||||||
|
private static final String REASON_PARAMETER = "newReason";
|
||||||
|
private static final String ID_PARAMETER = "id";
|
||||||
|
private static final String EDIT_INFRACTION_RESPONSE = "editInfraction_response";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionService infractionService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
Long infractionId = slashCommandParameterService.getCommandOption(ID_PARAMETER, event, Long.class, Integer.class).longValue();
|
||||||
|
String newReason = slashCommandParameterService.getCommandOption(REASON_PARAMETER, event, String.class);
|
||||||
|
return infractionService.editInfraction(infractionId, newReason, event.getGuild().getIdLong())
|
||||||
|
.thenCompose(unused -> interactionService.replyEmbed(EDIT_INFRACTION_RESPONSE, event))
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
List<Parameter> parameters = new ArrayList<>();
|
||||||
|
|
||||||
|
Parameter idParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(ID_PARAMETER)
|
||||||
|
.type(Long.class)
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
parameters.add(idParameter);
|
||||||
|
|
||||||
|
Parameter typeParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(REASON_PARAMETER)
|
||||||
|
.type(String.class)
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
parameters.add(typeParameter);
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.rootCommandName(ModerationSlashCommandNames.INFRACTIONS)
|
||||||
|
.commandName("edit")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(EDIT_INFRACTION_COMMAND)
|
||||||
|
.module(ModerationModuleDefinition.MODERATION)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.causesReaction(false)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.parameters(parameters)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.INFRACTIONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.command;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
|
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.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.ChannelService;
|
||||||
|
import dev.sheldan.abstracto.core.service.PaginatorService;
|
||||||
|
import dev.sheldan.abstracto.core.service.UserService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
|
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.moderation.config.ModerationModuleDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.InfractionParameter;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.template.command.InfractionEntry;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.template.command.InfractionsModel;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Infractions extends AbstractConditionableCommand {
|
||||||
|
|
||||||
|
private static final String INFRACTIONS_COMMAND = "infractions";
|
||||||
|
private static final String USER_PARAMETER = "user";
|
||||||
|
private static final String INFRACTIONS_RESPONSE_TEMPLATE = "infractions_display_response";
|
||||||
|
private static final String NO_INFRACTIONS_TEMPLATE_KEY = "infractions_no_infractions_found";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionManagementService infractionManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TemplateService templateService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PaginatorService paginatorService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SlashCommandParameterService slashCommandParameterService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||||
|
List<Infraction> infractions;
|
||||||
|
if(!commandContext.getParameters().getParameters().isEmpty()) {
|
||||||
|
Member member = (Member) commandContext.getParameters().getParameters().get(0);
|
||||||
|
if(!member.getGuild().equals(commandContext.getGuild())) {
|
||||||
|
throw new EntityGuildMismatchException();
|
||||||
|
}
|
||||||
|
infractions = infractionManagementService.getInfractionsForUser(userInServerManagementService.loadOrCreateUser(member));
|
||||||
|
} else {
|
||||||
|
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||||
|
infractions = infractionManagementService.getInfractionsForServer(server);
|
||||||
|
}
|
||||||
|
if(infractions.isEmpty()) {
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(NO_INFRACTIONS_TEMPLATE_KEY, new Object(), commandContext.getGuild().getIdLong());
|
||||||
|
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||||
|
.thenApply(unused -> CommandResult.fromSuccess());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
List<InfractionEntry> convertedInfractions = fromInfractions(infractions);
|
||||||
|
InfractionsModel model = InfractionsModel
|
||||||
|
.builder()
|
||||||
|
.entries(convertedInfractions)
|
||||||
|
.build();
|
||||||
|
return paginatorService.createPaginatorFromTemplate(INFRACTIONS_RESPONSE_TEMPLATE, model, commandContext.getChannel(), commandContext.getAuthor().getIdLong())
|
||||||
|
.thenApply(unused -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
|
List<Infraction> infractions;
|
||||||
|
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
||||||
|
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||||
|
if(!member.getGuild().equals(event.getGuild())) {
|
||||||
|
throw new EntityGuildMismatchException();
|
||||||
|
}
|
||||||
|
infractions = infractionManagementService.getInfractionsForUser(userInServerManagementService.loadOrCreateUser(member));
|
||||||
|
} else if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.STRING)){
|
||||||
|
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
||||||
|
Long userId = Long.parseLong(userIdStr);
|
||||||
|
AUserInAServer userInServer = userInServerManagementService.createUserInServer(event.getGuild().getIdLong(), userId);
|
||||||
|
infractions = infractionManagementService.getInfractionsForUser(userInServer);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
AServer server = serverManagementService.loadServer(event.getGuild());
|
||||||
|
infractions = infractionManagementService.getInfractionsForServer(server);
|
||||||
|
}
|
||||||
|
if(infractions.isEmpty()) {
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(NO_INFRACTIONS_TEMPLATE_KEY, new Object(), event.getGuild().getIdLong());
|
||||||
|
return interactionService.replyMessageToSend(messageToSend, event)
|
||||||
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
List<InfractionEntry> convertedInfractions = fromInfractions(infractions);
|
||||||
|
InfractionsModel model = InfractionsModel
|
||||||
|
.builder()
|
||||||
|
.entries(convertedInfractions)
|
||||||
|
.build();
|
||||||
|
return paginatorService.createPaginatorFromTemplate(INFRACTIONS_RESPONSE_TEMPLATE, model, event)
|
||||||
|
.thenApply(unused -> CommandResult.fromSuccess());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InfractionEntry> fromInfractions(List<Infraction> infractions) {
|
||||||
|
return infractions
|
||||||
|
.stream()
|
||||||
|
.map(this::fromInfraction)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfractionEntry fromInfraction(Infraction infraction) {
|
||||||
|
Map<String, String> parameters = infraction
|
||||||
|
.getParameters()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(infractionParameter -> infractionParameter.getInfractionParameterId().getName(), InfractionParameter::getValue));
|
||||||
|
return InfractionEntry
|
||||||
|
.builder()
|
||||||
|
.infractionId(infraction.getId())
|
||||||
|
.serverId(infraction.getServer().getId())
|
||||||
|
.decayed(infraction.getDecayed())
|
||||||
|
.decayDate(infraction.getDecayedDate())
|
||||||
|
.parameters(parameters)
|
||||||
|
.creationDate(infraction.getCreated())
|
||||||
|
.infractionUser(MemberDisplay.fromAUserInAServer(infraction.getUser()))
|
||||||
|
.infractionCreationUser(MemberDisplay.fromAUserInAServer(infraction.getInfractionCreator()))
|
||||||
|
.reason(infraction.getDescription())
|
||||||
|
.type(infraction.getType())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandConfiguration getConfiguration() {
|
||||||
|
List<Parameter> parameters = new ArrayList<>();
|
||||||
|
Parameter userParameter = Parameter
|
||||||
|
.builder()
|
||||||
|
.name(USER_PARAMETER)
|
||||||
|
.type(User.class)
|
||||||
|
.templated(true)
|
||||||
|
.optional(true)
|
||||||
|
.build();
|
||||||
|
parameters.add(userParameter);
|
||||||
|
|
||||||
|
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||||
|
.builder()
|
||||||
|
.enabled(true)
|
||||||
|
.rootCommandName(ModerationSlashCommandNames.INFRACTIONS)
|
||||||
|
.commandName("list")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.build();
|
||||||
|
return CommandConfiguration.builder()
|
||||||
|
.name(INFRACTIONS_COMMAND)
|
||||||
|
.module(ModerationModuleDefinition.MODERATION)
|
||||||
|
.templated(true)
|
||||||
|
.async(true)
|
||||||
|
.causesReaction(false)
|
||||||
|
.slashCommandConfig(slashCommandConfig)
|
||||||
|
.supportsEmbedException(true)
|
||||||
|
.parameters(parameters)
|
||||||
|
.help(helpInfo)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.INFRACTIONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
|||||||
import dev.sheldan.abstracto.core.command.config.*;
|
import dev.sheldan.abstracto.core.command.config.*;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
|||||||
import dev.sheldan.abstracto.core.command.config.*;
|
import dev.sheldan.abstracto.core.command.config.*;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||||
@@ -18,7 +18,6 @@ import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefiniti
|
|||||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
||||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -59,29 +58,19 @@ public class Mute extends AbstractConditionableCommand {
|
|||||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||||
Member member = (Member) parameters.get(0);
|
Member member = (Member) parameters.get(0);
|
||||||
Guild guild = commandContext.getGuild();
|
Guild guild = commandContext.getGuild();
|
||||||
GuildMessageChannel channel = commandContext.getChannel();
|
|
||||||
if(!member.getGuild().equals(guild)) {
|
if(!member.getGuild().equals(guild)) {
|
||||||
throw new EntityGuildMismatchException();
|
throw new EntityGuildMismatchException();
|
||||||
}
|
}
|
||||||
Duration duration = (Duration) parameters.get(1);
|
Duration duration = (Duration) parameters.get(1);
|
||||||
String defaultReason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
String defaultReason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
||||||
String reason = parameters.size() == 3 ? (String) parameters.get(2) : defaultReason;
|
String reason = parameters.size() == 3 ? (String) parameters.get(2) : defaultReason;
|
||||||
ServerChannelMessage context = ServerChannelMessage
|
|
||||||
.builder()
|
|
||||||
.serverId(guild.getIdLong())
|
|
||||||
.channelId(channel.getIdLong())
|
|
||||||
.messageId(commandContext.getMessage().getIdLong())
|
|
||||||
.build();
|
|
||||||
MuteContext muteLogModel = MuteContext
|
MuteContext muteLogModel = MuteContext
|
||||||
.builder()
|
.builder()
|
||||||
.muteDate(Instant.now())
|
|
||||||
.muteTargetDate(Instant.now().plus(duration))
|
.muteTargetDate(Instant.now().plus(duration))
|
||||||
.mutedUser(member)
|
.mutedUser(member)
|
||||||
|
.channelId(commandContext.getChannel().getIdLong())
|
||||||
.reason(reason)
|
.reason(reason)
|
||||||
.contextChannel(channel)
|
|
||||||
.message(commandContext.getMessage())
|
|
||||||
.mutingUser(commandContext.getAuthor())
|
.mutingUser(commandContext.getAuthor())
|
||||||
.context(context)
|
|
||||||
.build();
|
.build();
|
||||||
return muteService.muteMemberWithLog(muteLogModel)
|
return muteService.muteMemberWithLog(muteLogModel)
|
||||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||||
@@ -90,7 +79,6 @@ public class Mute extends AbstractConditionableCommand {
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||||
Guild guild = event.getGuild();
|
Guild guild = event.getGuild();
|
||||||
GuildMessageChannel channel = event.getGuildChannel();
|
|
||||||
Member targetMember = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, Member.class);
|
Member targetMember = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, Member.class);
|
||||||
String durationStr = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
String durationStr = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||||
Duration duration = ParseUtils.parseDuration(durationStr);
|
Duration duration = ParseUtils.parseDuration(durationStr);
|
||||||
@@ -100,20 +88,13 @@ public class Mute extends AbstractConditionableCommand {
|
|||||||
} else {
|
} else {
|
||||||
reason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
reason = templateService.renderSimpleTemplate(MUTE_DEFAULT_REASON_TEMPLATE, guild.getIdLong());
|
||||||
}
|
}
|
||||||
ServerChannelMessage context = ServerChannelMessage
|
|
||||||
.builder()
|
|
||||||
.serverId(guild.getIdLong())
|
|
||||||
.channelId(channel.getIdLong())
|
|
||||||
.build();
|
|
||||||
MuteContext muteLogModel = MuteContext
|
MuteContext muteLogModel = MuteContext
|
||||||
.builder()
|
.builder()
|
||||||
.muteDate(Instant.now())
|
|
||||||
.muteTargetDate(Instant.now().plus(duration))
|
.muteTargetDate(Instant.now().plus(duration))
|
||||||
.mutedUser(targetMember)
|
.mutedUser(targetMember)
|
||||||
.reason(reason)
|
.reason(reason)
|
||||||
.contextChannel(channel)
|
.channelId(event.getChannel().getIdLong())
|
||||||
.mutingUser(event.getMember())
|
.mutingUser(event.getMember())
|
||||||
.context(context)
|
|
||||||
.build();
|
.build();
|
||||||
return muteService.muteMemberWithLog(muteLogModel)
|
return muteService.muteMemberWithLog(muteLogModel)
|
||||||
.thenCompose(unused -> interactionService.replyEmbed(MUTE_RESPONSE, event))
|
.thenCompose(unused -> interactionService.replyEmbed(MUTE_RESPONSE, event))
|
||||||
@@ -146,7 +127,11 @@ public class Mute extends AbstractConditionableCommand {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
List<Parameter> parameters = Arrays.asList(userParameter, durationParameter, reasonParameter);
|
List<Parameter> parameters = Arrays.asList(userParameter, durationParameter, reasonParameter);
|
||||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
HelpInfo helpInfo = HelpInfo
|
||||||
|
.builder()
|
||||||
|
.templated(true)
|
||||||
|
.hasExample(true)
|
||||||
|
.build();
|
||||||
EffectConfig muteEffect = EffectConfig
|
EffectConfig muteEffect = EffectConfig
|
||||||
.builder()
|
.builder()
|
||||||
.position(0)
|
.position(0)
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.config.*;
|
|||||||
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.command;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
|
||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
|
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class SetMuteRole extends AbstractConditionableCommand {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MuteRoleManagementService muteRoleManagementService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RoleManagementService roleManagementService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ServerManagementService serverManagementService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommandResult execute(CommandContext commandContext) {
|
|
||||||
Role jdaRole = (Role) commandContext.getParameters().getParameters().get(0);
|
|
||||||
if(!jdaRole.getGuild().equals(commandContext.getGuild())) {
|
|
||||||
throw new EntityGuildMismatchException();
|
|
||||||
}
|
|
||||||
ARole role = roleManagementService.findRole(jdaRole.getIdLong());
|
|
||||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
|
||||||
muteRoleManagementService.setMuteRoleForServer(server, role);
|
|
||||||
return CommandResult.fromSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommandConfiguration getConfiguration() {
|
|
||||||
List<Parameter> parameters = new ArrayList<>();
|
|
||||||
parameters.add(Parameter.builder().name("role").templated(true).type(Role.class).build());
|
|
||||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
|
||||||
return CommandConfiguration.builder()
|
|
||||||
.name("setMuteRole")
|
|
||||||
.module(ModerationModuleDefinition.MODERATION)
|
|
||||||
.templated(true)
|
|
||||||
.supportsEmbedException(true)
|
|
||||||
.causesReaction(true)
|
|
||||||
.parameters(parameters)
|
|
||||||
.help(helpInfo)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FeatureDefinition getFeature() {
|
|
||||||
return ModerationFeatureDefinition.MUTING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
import dev.sheldan.abstracto.core.service.UserService;
|
import dev.sheldan.abstracto.core.service.UserService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
@@ -53,7 +53,7 @@ public class UnMute extends AbstractConditionableCommand {
|
|||||||
throw new EntityGuildMismatchException();
|
throw new EntityGuildMismatchException();
|
||||||
}
|
}
|
||||||
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(member);
|
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(member);
|
||||||
return muteService.unMuteUser(userToUnMute).thenApply(aVoid ->
|
return muteService.unMuteUser(userToUnMute, commandContext.getAuthor()).thenApply(aVoid ->
|
||||||
CommandResult.fromSuccess()
|
CommandResult.fromSuccess()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ public class UnMute extends AbstractConditionableCommand {
|
|||||||
throw new EntityGuildMismatchException();
|
throw new EntityGuildMismatchException();
|
||||||
}
|
}
|
||||||
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(targetMember);
|
AUserInAServer userToUnMute = userInServerManagementService.loadOrCreateUser(targetMember);
|
||||||
return muteService.unMuteUser(userToUnMute)
|
return muteService.unMuteUser(userToUnMute, event.getMember())
|
||||||
.thenCompose(unused -> interactionService.replyEmbed(UN_MUTE_RESPONSE, event))
|
.thenCompose(unused -> interactionService.replyEmbed(UN_MUTE_RESPONSE, event))
|
||||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
|||||||
import dev.sheldan.abstracto.core.command.config.*;
|
import dev.sheldan.abstracto.core.command.config.*;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
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.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
|
|||||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||||
import dev.sheldan.abstracto.core.command.config.SlashCommandConfig;
|
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||||
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
|
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
|||||||
@@ -21,4 +21,9 @@ public class ModerationListenerConfig {
|
|||||||
return executorService.setupExecutorFor("warningCreatedListener");
|
return executorService.setupExecutorFor("warningCreatedListener");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "reportMessageCreatedExecutor")
|
||||||
|
public TaskExecutor reportMessageCreatedExecutor() {
|
||||||
|
return executorService.setupExecutorFor("reportMessageCreatedListener");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
|||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
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.MemberDisplay;
|
||||||
import dev.sheldan.abstracto.core.service.MemberService;
|
import dev.sheldan.abstracto.core.service.MemberService;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteEntry;
|
import dev.sheldan.abstracto.moderation.model.template.command.MuteEntry;
|
||||||
@@ -25,9 +24,6 @@ public class MuteEntryConverter {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MemberService memberService;
|
private MemberService memberService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MuteManagementService muteManagementService;
|
private MuteManagementService muteManagementService;
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,18 @@ import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
|||||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncJoinListener;
|
import dev.sheldan.abstracto.core.listener.async.jda.AsyncJoinListener;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.models.listener.MemberJoinModel;
|
import dev.sheldan.abstracto.core.models.listener.MemberJoinModel;
|
||||||
|
import dev.sheldan.abstracto.core.service.MemberService;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class JoinMuteListener implements AsyncJoinListener {
|
public class JoinMuteListener implements AsyncJoinListener {
|
||||||
@@ -21,17 +25,15 @@ public class JoinMuteListener implements AsyncJoinListener {
|
|||||||
private MuteManagementService muteManagementService;
|
private MuteManagementService muteManagementService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MuteService muteService;
|
private MemberService memberService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultListenerResult execute(MemberJoinModel model) {
|
public DefaultListenerResult execute(MemberJoinModel model) {
|
||||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(model.getServerId(), model.getJoiningUser().getUserId());
|
Optional<Mute> optionalMute = muteManagementService.getAMuteOfOptional(model.getMember());
|
||||||
if(muteManagementService.hasActiveMute(aUserInAServer)) {
|
if(optionalMute.isPresent()) {
|
||||||
log.info("Re-muting user {} which joined the server {}, because the mute has not ended yet.", model.getJoiningUser().getUserId(), model.getServerId());
|
log.info("Re-muting user {} which joined the server {}, because the mute has not ended yet.", model.getJoiningUser().getUserId(), model.getServerId());
|
||||||
muteService.applyMuteRole(aUserInAServer);
|
Mute mute = optionalMute.get();
|
||||||
|
memberService.timeoutUser(model.getMember(), mute.getMuteTargetDate());
|
||||||
}
|
}
|
||||||
return DefaultListenerResult.PROCESSED;
|
return DefaultListenerResult.PROCESSED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
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.service.MemberService;
|
||||||
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
|
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.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.template.command.MuteListenerModel;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.MuteServiceBean;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.audit.ActionType;
|
||||||
|
import net.dv8tion.jda.api.audit.AuditLogEntry;
|
||||||
|
import net.dv8tion.jda.api.audit.AuditLogKey;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class MemberTimeoutListener implements AsyncMemberTimeoutUpdatedListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TemplateService templateService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PostTargetService postTargetService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberTimeoutListener self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberService memberService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultListenerResult execute(MemberTimeoutUpdatedModel model) {
|
||||||
|
Guild guild = model.getGuild();
|
||||||
|
guild.retrieveAuditLogs()
|
||||||
|
.type(ActionType.MEMBER_UPDATE)
|
||||||
|
.limit(10)
|
||||||
|
.queue(auditLogEntries -> {
|
||||||
|
CompletableFuture<Void> notificationFuture = null;
|
||||||
|
if(auditLogEntries.isEmpty()) {
|
||||||
|
log.info("Did not find recent timeouts in guild {}.", model.getServerId());
|
||||||
|
notificationFuture = self.sendMutingUpdateNotification(model, null);
|
||||||
|
} else {
|
||||||
|
Optional<AuditLogEntry> timeoutEntryOptional = auditLogEntries
|
||||||
|
.stream()
|
||||||
|
.filter(auditLogEntry -> auditLogEntry.getChangeByKey(AuditLogKey.MEMBER_TIME_OUT) != null
|
||||||
|
&& auditLogEntry.getTargetIdLong() == model.getTimeoutUser().getUserId())
|
||||||
|
.findFirst();
|
||||||
|
if(timeoutEntryOptional.isPresent()) {
|
||||||
|
AuditLogEntry auditLogEntry = timeoutEntryOptional.get();
|
||||||
|
User responsibleUser = auditLogEntry.getUser();
|
||||||
|
if(guild.getSelfMember().getIdLong() != responsibleUser.getIdLong()) {
|
||||||
|
notificationFuture = self.sendMutingUpdateNotification(model, auditLogEntry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notificationFuture = self.sendMutingUpdateNotification(model, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(notificationFuture != null) {
|
||||||
|
notificationFuture.thenAccept(unused -> {
|
||||||
|
log.info("Sent notification about timeout change {} -> {} of user {} in server {}.",
|
||||||
|
model.getOldTimeout(), model.getNewTimeout(), model.getTimeoutUser().getUserId(), model.getServerId());
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.info("Sent notification about timeout change {} -> {} of user {} in server {}.",
|
||||||
|
model.getOldTimeout(), model.getNewTimeout(), model.getTimeoutUser().getUserId(), model.getServerId());
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return DefaultListenerResult.PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CompletableFuture<Void> sendMutingUpdateNotification(MemberTimeoutUpdatedModel model, AuditLogEntry logEntry) {
|
||||||
|
User responsibleUser;
|
||||||
|
Guild guild = model.getGuild();
|
||||||
|
CompletableFuture<Member> future;
|
||||||
|
String reason;
|
||||||
|
if(logEntry != null) {
|
||||||
|
responsibleUser = logEntry.getUser();
|
||||||
|
if(responsibleUser != null) {
|
||||||
|
ServerUser responsibleServerUser = ServerUser
|
||||||
|
.builder()
|
||||||
|
.serverId(guild.getIdLong())
|
||||||
|
.isBot(responsibleUser.isBot())
|
||||||
|
.userId(responsibleUser.getIdLong())
|
||||||
|
.build();
|
||||||
|
future = memberService.retrieveMemberInServer(responsibleServerUser);
|
||||||
|
} else {
|
||||||
|
future = CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
reason = logEntry.getReason();
|
||||||
|
} else {
|
||||||
|
future = CompletableFuture.completedFuture(null);
|
||||||
|
reason = null;
|
||||||
|
}
|
||||||
|
CompletableFuture<Void> returningFuture = new CompletableFuture<>();
|
||||||
|
future.whenComplete((aVoid, throwable) -> {
|
||||||
|
try {
|
||||||
|
MuteListenerModel muteLogModel = MuteListenerModel
|
||||||
|
.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())
|
||||||
|
.reason(reason)
|
||||||
|
.build();
|
||||||
|
MessageToSend message = templateService.renderEmbedTemplate(MuteServiceBean.MUTE_LOG_TEMPLATE, muteLogModel, guild.getIdLong());
|
||||||
|
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, model.getServerId()));
|
||||||
|
returningFuture.complete(null);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
log.error("Failed to log timeout update event for user {} in guild {}.", model.getTimeoutUser().getUserId(), model.getServerId(), exception);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return returningFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.MUTING;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,9 +48,14 @@ public class ReactionReportListener implements AsyncReactionAddedListener {
|
|||||||
memberService.retrieveMemberInServer(model.getUserReacting())
|
memberService.retrieveMemberInServer(model.getUserReacting())
|
||||||
.thenCompose(member -> reactionService.removeReactionFromMessage(model.getReaction(), cachedMessage, member.getUser()))
|
.thenCompose(member -> reactionService.removeReactionFromMessage(model.getReaction(), cachedMessage, member.getUser()))
|
||||||
.thenAccept(unused -> log.info("Removed report reaction on message {} in server {} in channel {}.", cachedMessage.getMessageId(), serverId, cachedMessage.getChannelId()));
|
.thenAccept(unused -> log.info("Removed report reaction on message {} in server {} in channel {}.", cachedMessage.getMessageId(), serverId, cachedMessage.getChannelId()));
|
||||||
log.info("User {} in server {} reacted to report a message {} from channel {}.",
|
|
||||||
model.getUserReacting().getUserId(), model.getServerId(), cachedMessage.getMessageId(), cachedMessage.getChannelId());
|
if(!reactionReportService.allowedToReport(model.getUserReacting())) {
|
||||||
reactionReportService.createReactionReport(cachedMessage, model.getUserReacting()).exceptionally(throwable -> {
|
log.info("User {} was reported on message {} in server {} within the cooldown. Ignoring.",
|
||||||
|
cachedMessage.getAuthor().getAuthorId(), cachedMessage.getMessageId(), cachedMessage.getServerId());
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
|
||||||
|
reactionReportService.createReactionReport(cachedMessage, model.getUserReacting(), null).exceptionally(throwable -> {
|
||||||
log.error("Failed to create reaction report in server {} on message {} in channel {}.", serverId, cachedMessage.getMessageId(), cachedMessage.getChannelId(), throwable);
|
log.error("Failed to create reaction report in server {} on message {} in channel {}.", serverId, cachedMessage.getMessageId(), cachedMessage.getChannelId(), throwable);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
|||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncUserBannedListener;
|
import dev.sheldan.abstracto.core.listener.async.jda.AsyncUserBannedListener;
|
||||||
import dev.sheldan.abstracto.core.models.listener.UserBannedModel;
|
import dev.sheldan.abstracto.core.models.listener.UserBannedModel;
|
||||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
@@ -27,9 +26,6 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class UserBannedListener implements AsyncUserBannedListener {
|
public class UserBannedListener implements AsyncUserBannedListener {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FeatureModeService featureModeService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TemplateService templateService;
|
private TemplateService templateService;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.infraction;
|
||||||
|
|
||||||
|
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.service.ChannelService;
|
||||||
|
import dev.sheldan.abstracto.core.service.MemberService;
|
||||||
|
import dev.sheldan.abstracto.core.service.MessageService;
|
||||||
|
import dev.sheldan.abstracto.core.service.UserService;
|
||||||
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.listener.InfractionUpdatedDescriptionListener;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.InfractionParameter;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.listener.InfractionDescriptionEventModel;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.template.command.BanLog;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.BanServiceBean;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class BanReasonUpdatedListener implements InfractionUpdatedDescriptionListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionManagementService infractionManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberService memberService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BanServiceBean banServiceBean;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BanReasonUpdatedListener self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageService messageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DefaultListenerResult> execute(InfractionDescriptionEventModel model) {
|
||||||
|
Infraction infraction = infractionManagementService.loadInfraction(model.getInfractionId());
|
||||||
|
CompletableFuture<User> infractionUser = userService.retrieveUserForId(infraction.getUser().getUserReference().getId());
|
||||||
|
CompletableFuture<Member> creatorUser = memberService.retrieveMemberInServer(ServerUser.fromAUserInAServer(infraction.getInfractionCreator()));
|
||||||
|
CompletableFuture<DefaultListenerResult> returningFuture = new CompletableFuture<>();
|
||||||
|
Long infractionId = infraction.getId();
|
||||||
|
CompletableFuture.allOf(infractionUser, creatorUser)
|
||||||
|
.whenComplete((unused, throwable) -> {
|
||||||
|
if(throwable != null) {
|
||||||
|
log.warn("Failed to load members for infraction update of ban {} in server {}.", infractionId, model.getServerId(), throwable);
|
||||||
|
}
|
||||||
|
self.handleBanUpdate(model, infractionUser, creatorUser, returningFuture);
|
||||||
|
});
|
||||||
|
return returningFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void handleBanUpdate(InfractionDescriptionEventModel model, CompletableFuture<User> infractionUser, CompletableFuture<Member> infractionCreator, CompletableFuture<DefaultListenerResult> returningFuture) {
|
||||||
|
Infraction infraction = infractionManagementService.loadInfraction(model.getInfractionId());
|
||||||
|
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(model.getServerId(), infraction.getLogChannel().getId());
|
||||||
|
Integer deletionDays = infraction
|
||||||
|
.getParameters()
|
||||||
|
.stream()
|
||||||
|
.filter(infractionParameter -> infractionParameter.getInfractionParameterId().getName().equals(BanService.INFRACTION_PARAMETER_DELETION_DAYS_KEY))
|
||||||
|
.findAny()
|
||||||
|
.map(InfractionParameter::getValue)
|
||||||
|
.map(Integer::parseInt)
|
||||||
|
.orElse(0);
|
||||||
|
BanLog banLog = BanLog
|
||||||
|
.builder()
|
||||||
|
.bannedUser(infractionUser.isCompletedExceptionally() ? null : infractionUser.join())
|
||||||
|
.banningMember(infractionCreator.isCompletedExceptionally() ? null : infractionCreator.join())
|
||||||
|
.deletionDays(deletionDays)
|
||||||
|
.reason(model.getNewDescription())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
MessageToSend message = banServiceBean.renderBanMessage(banLog, model.getServerId());
|
||||||
|
messageService.editMessageInChannel(messageChannel, message, infraction.getLogMessageId())
|
||||||
|
.thenAccept(unused1 -> returningFuture.complete(DefaultListenerResult.PROCESSED))
|
||||||
|
.exceptionally(throwable1 -> {
|
||||||
|
returningFuture.complete(DefaultListenerResult.PROCESSED);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean handlesEvent(InfractionDescriptionEventModel model) {
|
||||||
|
return model.getType().equals(BanService.BAN_INFRACTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.MODERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPriority() {
|
||||||
|
return ListenerPriority.MEDIUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.infraction;
|
||||||
|
|
||||||
|
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.service.ChannelService;
|
||||||
|
import dev.sheldan.abstracto.core.service.GuildService;
|
||||||
|
import dev.sheldan.abstracto.core.service.MemberService;
|
||||||
|
import dev.sheldan.abstracto.core.service.MessageService;
|
||||||
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.listener.InfractionUpdatedDescriptionListener;
|
||||||
|
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.service.WarnServiceBean;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class WarnReasonUpdatedListener implements InfractionUpdatedDescriptionListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WarnManagementService warnManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WarnServiceBean warnService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionManagementService infractionManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MemberService memberService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageService messageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WarnReasonUpdatedListener self;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DefaultListenerResult> execute(InfractionDescriptionEventModel model) {
|
||||||
|
Optional<Warning> potentialWarning = warnManagementService.findWarnByInfraction(model.getInfractionId());
|
||||||
|
if(potentialWarning.isPresent()) {
|
||||||
|
Warning warning = potentialWarning.get();
|
||||||
|
Long warnId = warning.getWarnId().getId();
|
||||||
|
CompletableFuture<Member> warnedUser = memberService.retrieveMemberInServer(ServerUser.fromAUserInAServer(warning.getWarnedUser()));
|
||||||
|
CompletableFuture<Member> warningUser = memberService.retrieveMemberInServer(ServerUser.fromAUserInAServer(warning.getWarningUser()));
|
||||||
|
CompletableFuture<DefaultListenerResult> returningFuture = new CompletableFuture<>();
|
||||||
|
CompletableFuture.allOf(warnedUser, warningUser)
|
||||||
|
.whenComplete((unused, throwable) -> {
|
||||||
|
if(throwable != null) {
|
||||||
|
log.warn("Failed to load members for infraction update of warning {} in server {}.", warnId, model.getServerId(), throwable);
|
||||||
|
}
|
||||||
|
self.handleWarnUpdate(model, warnId, warnedUser, warningUser, returningFuture);
|
||||||
|
});
|
||||||
|
return returningFuture;
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.completedFuture(DefaultListenerResult.IGNORED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleWarnUpdate(InfractionDescriptionEventModel model, Long warnId, CompletableFuture<Member> warnedUser, CompletableFuture<Member> warningUser, CompletableFuture<DefaultListenerResult> returningFuture) {
|
||||||
|
Guild guild = guildService.getGuildById(model.getServerId());
|
||||||
|
Infraction infraction = infractionManagementService.loadInfraction(model.getInfractionId());
|
||||||
|
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(model.getServerId(), infraction.getLogChannel().getId());
|
||||||
|
WarnContext context = WarnContext
|
||||||
|
.builder()
|
||||||
|
.warnedMember(warnedUser.isCompletedExceptionally() ? null : warnedUser.join())
|
||||||
|
.member(warningUser.isCompletedExceptionally() ? null : warningUser.join())
|
||||||
|
.reason(model.getNewDescription())
|
||||||
|
.warnId(warnId)
|
||||||
|
.guild(guild)
|
||||||
|
.build();
|
||||||
|
MessageToSend message = warnService.renderMessageModel(context);
|
||||||
|
messageService.editMessageInChannel(messageChannel, message, infraction.getLogMessageId())
|
||||||
|
.thenAccept(unused1 -> returningFuture.complete(DefaultListenerResult.PROCESSED))
|
||||||
|
.exceptionally(throwable1 -> {
|
||||||
|
returningFuture.complete(DefaultListenerResult.PROCESSED);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean handlesEvent(InfractionDescriptionEventModel model) {
|
||||||
|
return model.getType().equals(WarnServiceBean.WARN_INFRACTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPriority() {
|
||||||
|
return ListenerPriority.MEDIUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.interaction;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.MessageContextConfig;
|
||||||
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.context.message.listener.MessageContextCommandListener;
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
|
import dev.sheldan.abstracto.core.models.listener.interaction.MessageContextInteractionModel;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.context.ContextCommandService;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.ReactionReportService;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.ReactionReportServiceBean;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static dev.sheldan.abstracto.moderation.service.ReactionReportServiceBean.REACTION_REPORT_RESPONSE_TEMPLATE;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class ReportContextCommandListener implements MessageContextCommandListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ContextCommandService contextCommandService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReactionReportService reactionReportService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultListenerResult execute(MessageContextInteractionModel model) {
|
||||||
|
Message targetMessage = model.getEvent().getTarget();
|
||||||
|
if(targetMessage.getAuthor().getIdLong() == model.getEvent().getUser().getIdLong()) {
|
||||||
|
interactionService.replyEmbed(ReactionReportServiceBean.REACTION_REPORT_OWN_MESSAGE_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
ServerUser userReporting = ServerUser
|
||||||
|
.builder()
|
||||||
|
.serverId(model.getServerId())
|
||||||
|
.userId(model.getEvent().getUser().getIdLong())
|
||||||
|
.isBot(model.getEvent().getUser().isBot())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if(!reactionReportService.allowedToReport(userReporting)) {
|
||||||
|
log.info("User {} was reported on message {} in server {} within the cooldown. Ignoring.",
|
||||||
|
targetMessage.getAuthor().getIdLong(), targetMessage.getIdLong(), targetMessage.getGuild().getIdLong());
|
||||||
|
interactionService.replyEmbed(ReactionReportServiceBean.REACTION_REPORT_COOLDOWN_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
|
||||||
|
reactionReportService.createReactionReport(targetMessage, userReporting, null).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to create reaction report in server {} on message {} in channel {} with interaction.",
|
||||||
|
model.getServerId(), targetMessage.getIdLong(), model.getEvent().getChannel().getIdLong(), throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
interactionService.replyEmbed(REACTION_REPORT_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
|
||||||
|
return DefaultListenerResult.PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageContextConfig getConfig() {
|
||||||
|
return MessageContextConfig
|
||||||
|
.builder()
|
||||||
|
.isTemplated(true)
|
||||||
|
.name("report_message")
|
||||||
|
.templateKey("report_message_context_menu_label")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean handlesEvent(MessageContextInteractionModel model) {
|
||||||
|
return contextCommandService.matchesGuildContextName(model, getConfig(), model.getServerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.REPORT_REACTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.interaction;
|
||||||
|
|
||||||
|
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.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.service.MessageCache;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.interaction.MessageReportModalPayload;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.ReactionReportService;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static dev.sheldan.abstracto.moderation.service.ReactionReportServiceBean.REACTION_REPORT_RESPONSE_TEMPLATE;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class ReportContextModalListener implements ModalInteractionListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MessageCache messageCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReactionReportService reactionReportService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModalInteractionListenerResult execute(ModalInteractionListenerModel model) {
|
||||||
|
MessageReportModalPayload payload = (MessageReportModalPayload) model.getDeserializedPayload();
|
||||||
|
String context = model
|
||||||
|
.getEvent()
|
||||||
|
.getValues()
|
||||||
|
.stream()
|
||||||
|
.filter(modalMapping -> modalMapping.getId().equals(payload.getTextInputId()))
|
||||||
|
.map(ModalMapping::getAsString)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
messageCache.getMessageFromCache(payload.getServerId(), payload.getChannelId(), payload.getMessageId()).thenAccept(cachedMessage -> {
|
||||||
|
ServerUser userReporting = ServerUser
|
||||||
|
.builder()
|
||||||
|
.serverId(model.getServerId())
|
||||||
|
.userId(cachedMessage.getAuthor().getAuthorId())
|
||||||
|
.isBot(cachedMessage.getAuthor().getIsBot())
|
||||||
|
.build();
|
||||||
|
reactionReportService.createReactionReport(cachedMessage, userReporting, context)
|
||||||
|
.thenAccept(unused -> {
|
||||||
|
interactionService.replyEmbed(REACTION_REPORT_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
log.info("Handled modal for message report with id {} in guild {} in channel {} on message {}",
|
||||||
|
model.getEvent().getModalId(), payload.getServerId(), payload.getChannelId(), payload.getMessageId());
|
||||||
|
componentPayloadManagementService.deletePayload(payload.getModalId());
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to create reaction report in server {} on message {} in channel {} with interaction.",
|
||||||
|
model.getServerId(), cachedMessage.getMessageId(), model.getEvent().getChannel().getIdLong(), throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to load reported message.", throwable);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return ModalInteractionListenerResult.ACKNOWLEDGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.REPORT_REACTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPriority() {
|
||||||
|
return ListenerPriority.MEDIUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean handlesEvent(ModalInteractionListenerModel model) {
|
||||||
|
return model.getDeserializedPayload() instanceof MessageReportModalPayload && model.getEvent().isFromGuild();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.interaction;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.MessageContextConfig;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.modal.ModalConfigPayload;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.modal.ModalService;
|
||||||
|
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.context.message.listener.MessageContextCommandListener;
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
|
import dev.sheldan.abstracto.core.models.listener.interaction.MessageContextInteractionModel;
|
||||||
|
import dev.sheldan.abstracto.core.interaction.context.ContextCommandService;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.interaction.MessageReportModalPayload;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.template.listener.ReportInputModalModel;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.ReactionReportService;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.ReactionReportServiceBean;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class ReportWithContextContextCommandListener implements MessageContextCommandListener {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ContextCommandService contextCommandService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ModalService modalService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComponentService componentService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReportWithContextContextCommandListener self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReactionReportService reactionReportService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InteractionService interactionService;
|
||||||
|
|
||||||
|
private static final String REACTION_REPORT_MODAL_TEMPLATE = "reactionReport_input";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultListenerResult execute(MessageContextInteractionModel model) {
|
||||||
|
Message targetMessage = model.getEvent().getTarget();
|
||||||
|
if(targetMessage.getAuthor().getIdLong() == model.getEvent().getUser().getIdLong()) {
|
||||||
|
interactionService.replyEmbed(ReactionReportServiceBean.REACTION_REPORT_OWN_MESSAGE_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
ServerUser userReporting = ServerUser
|
||||||
|
.builder()
|
||||||
|
.serverId(model.getServerId())
|
||||||
|
.userId(model.getEvent().getUser().getIdLong())
|
||||||
|
.isBot(model.getEvent().getUser().isBot())
|
||||||
|
.build();
|
||||||
|
if(!reactionReportService.allowedToReport(userReporting)) {
|
||||||
|
log.info("User {} was reported on message {} in server {} within the cooldown. Ignoring.",
|
||||||
|
targetMessage.getAuthor().getIdLong(), targetMessage.getIdLong(), targetMessage.getGuild().getIdLong());
|
||||||
|
interactionService.replyEmbed(ReactionReportServiceBean.REACTION_REPORT_COOLDOWN_RESPONSE_TEMPLATE, new Object(), model.getEvent());
|
||||||
|
return DefaultListenerResult.IGNORED;
|
||||||
|
}
|
||||||
|
|
||||||
|
String modalId = componentService.generateComponentId();
|
||||||
|
String textInputId = componentService.generateComponentId();
|
||||||
|
|
||||||
|
ReportInputModalModel modalModel = ReportInputModalModel
|
||||||
|
.builder()
|
||||||
|
.modalId(modalId)
|
||||||
|
.inputComponentId(textInputId)
|
||||||
|
.build();
|
||||||
|
modalService.replyModal(model.getEvent(), REACTION_REPORT_MODAL_TEMPLATE, modalModel)
|
||||||
|
.thenAccept(unused -> {
|
||||||
|
log.info("Created modal for report on message {} from user {} in server {}.",
|
||||||
|
targetMessage.getIdLong(), targetMessage.getAuthor().getIdLong(), targetMessage.getGuild().getIdLong());
|
||||||
|
self.persistModalPayload(targetMessage, modalId, textInputId);
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
log.error("Failed to create modal for report on message {} from user {} in server {}.",
|
||||||
|
targetMessage.getIdLong(), targetMessage.getAuthor().getIdLong(), targetMessage.getGuild().getIdLong());
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return DefaultListenerResult.PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void persistModalPayload(Message message, String modalId, String inputId) {
|
||||||
|
MessageReportModalPayload payload = MessageReportModalPayload
|
||||||
|
.builder()
|
||||||
|
.channelId(message.getChannel().getIdLong())
|
||||||
|
.messageId(message.getIdLong())
|
||||||
|
.serverId(message.getGuild().getIdLong())
|
||||||
|
.modalId(modalId)
|
||||||
|
.textInputId(inputId)
|
||||||
|
.build();
|
||||||
|
ModalConfigPayload payloadConfig = ModalConfigPayload
|
||||||
|
.builder()
|
||||||
|
.modalPayload(payload)
|
||||||
|
.origin(ReactionReportServiceBean.REACTION_REPORT_MODAL_ORIGIN)
|
||||||
|
.payloadType(payload.getClass())
|
||||||
|
.modalId(modalId)
|
||||||
|
.build();
|
||||||
|
componentPayloadManagementService.createModalPayload(payloadConfig, message.getGuild().getIdLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageContextConfig getConfig() {
|
||||||
|
return MessageContextConfig
|
||||||
|
.builder()
|
||||||
|
.isTemplated(true)
|
||||||
|
.name("report_message_context")
|
||||||
|
.templateKey("report_message_with_context_context_menu_label")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean handlesEvent(MessageContextInteractionModel model) {
|
||||||
|
return contextCommandService.matchesGuildContextName(model, getConfig(), model.getServerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureDefinition getFeature() {
|
||||||
|
return ModerationFeatureDefinition.REPORT_REACTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.listener.manager;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.listener.ListenerService;
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||||
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
|
import dev.sheldan.abstracto.moderation.listener.ReportMessageCreatedListener;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.listener.ReportMessageCreatedModel;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.core.task.TaskExecutor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ReportMessageCreatedListenerManager {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<ReportMessageCreatedListener> listeners;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ListenerService listenerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("reportMessageCreatedExecutor")
|
||||||
|
private TaskExecutor reportMessageCreatedExecutor;
|
||||||
|
|
||||||
|
public void sendReportMessageCreatedEvent(CachedMessage cachedMessage, Message message, ServerUser reporter) {
|
||||||
|
if(listeners == null || listeners.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ReportMessageCreatedModel model = createEventModel(cachedMessage, message, reporter);
|
||||||
|
listeners.forEach(listener -> listenerService.executeFeatureAwareListener(listener, model, reportMessageCreatedExecutor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReportMessageCreatedModel createEventModel(CachedMessage reportedMessage, Message message, ServerUser reporter) {
|
||||||
|
return ReportMessageCreatedModel
|
||||||
|
.builder()
|
||||||
|
.reportedMessage(ServerChannelMessage.fromCachedMessage(reportedMessage))
|
||||||
|
.reportMessage(ServerChannelMessage.fromMessage(message))
|
||||||
|
.reporter(reporter)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.repository;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.InfractionParameter;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.embedded.InfractionParameterId;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface InfractionParameterRepository extends JpaRepository<InfractionParameter, InfractionParameterId> {
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.sheldan.abstracto.moderation.repository;
|
package dev.sheldan.abstracto.moderation.repository;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
@@ -10,4 +11,6 @@ import java.util.List;
|
|||||||
@Repository
|
@Repository
|
||||||
public interface InfractionRepository extends JpaRepository<Infraction, Long> {
|
public interface InfractionRepository extends JpaRepository<Infraction, Long> {
|
||||||
List<Infraction> findByUserAndDecayedFalse(AUserInAServer aUserInAServer);
|
List<Infraction> findByUserAndDecayedFalse(AUserInAServer aUserInAServer);
|
||||||
|
List<Infraction> findByUserOrderByCreated(AUserInAServer aUserInAServer);
|
||||||
|
List<Infraction> findByServerOrderByCreated(AServer server);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Optional;
|
|||||||
public interface MuteRepository extends JpaRepository<Mute, ServerSpecificId> {
|
public interface MuteRepository extends JpaRepository<Mute, ServerSpecificId> {
|
||||||
boolean existsByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
|
boolean existsByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
|
||||||
|
|
||||||
Mute findTopByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
|
Optional<Mute> findTopByMutedUserAndMuteEndedFalse(AUserInAServer userInAServer);
|
||||||
|
|
||||||
List<Mute> findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(AUserInAServer aUserInAServer);
|
List<Mute> findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(AUserInAServer aUserInAServer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.repository;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.MuteRole;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface MuteRoleRepository extends JpaRepository<MuteRole, Long> {
|
|
||||||
|
|
||||||
MuteRole findByRoleServer(AServer server);
|
|
||||||
|
|
||||||
List<MuteRole> findAllByRoleServer(AServer server);
|
|
||||||
|
|
||||||
boolean existsByRoleServer(AServer server);
|
|
||||||
}
|
|
||||||
@@ -6,10 +6,11 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface ReactionReportRepository extends JpaRepository<ReactionReport, Long> {
|
public interface ReactionReportRepository extends JpaRepository<ReactionReport, Long> {
|
||||||
|
|
||||||
Optional<ReactionReport> findByReportedUserAndCreatedLessThan(AUserInAServer aUserInAServer, Instant maxCreated);
|
List<ReactionReport> findByReportedUserAndCreatedLessThan(AUserInAServer aUserInAServer, Instant maxCreated);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
|||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
import dev.sheldan.abstracto.moderation.model.database.Warning;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@@ -27,6 +26,6 @@ public interface WarnRepository extends JpaRepository<Warning, ServerSpecificId>
|
|||||||
|
|
||||||
List<Warning> findByWarnedUser(AUserInAServer aUserInAServer);
|
List<Warning> findByWarnedUser(AUserInAServer aUserInAServer);
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Optional<Warning> findByWarnId_IdAndWarnId_ServerId(Long warnId, Long serverId);
|
Optional<Warning> findByWarnId_IdAndWarnId_ServerId(Long warnId, Long serverId);
|
||||||
|
Optional<Warning> findByInfraction_Id(Long infractionId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service;
|
package dev.sheldan.abstracto.moderation.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.service.*;
|
import dev.sheldan.abstracto.core.service.*;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureConfig;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.ModerationPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.ModerationPostTarget;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.moderation.model.BanResult;
|
import dev.sheldan.abstracto.moderation.model.BanResult;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.BanLog;
|
import dev.sheldan.abstracto.moderation.model.template.command.BanLog;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.BanNotificationModel;
|
import dev.sheldan.abstracto.moderation.model.template.command.BanNotificationModel;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.UnBanLog;
|
import dev.sheldan.abstracto.moderation.model.template.command.UnBanLog;
|
||||||
@@ -13,8 +18,12 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import net.dv8tion.jda.api.entities.*;
|
import net.dv8tion.jda.api.entities.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -37,6 +46,18 @@ public class BanServiceBean implements BanService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MessageService messageService;
|
private MessageService messageService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FeatureFlagService featureFlagService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigService configService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionService infractionService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<BanResult> banUserWithNotification(User user, String reason, Member banningMember, Integer deletionDays) {
|
public CompletableFuture<BanResult> banUserWithNotification(User user, String reason, Member banningMember, Integer deletionDays) {
|
||||||
BanLog banLog = BanLog
|
BanLog banLog = BanLog
|
||||||
@@ -47,18 +68,31 @@ public class BanServiceBean implements BanService {
|
|||||||
.reason(reason)
|
.reason(reason)
|
||||||
.build();
|
.build();
|
||||||
Guild guild = banningMember.getGuild();
|
Guild guild = banningMember.getGuild();
|
||||||
CompletableFuture<BanResult> returningFuture = new CompletableFuture<>();
|
BanResult[] result = {BanResult.SUCCESSFUL};
|
||||||
sendBanNotification(user, reason, guild)
|
return sendBanNotification(user, reason, guild)
|
||||||
.whenComplete((unused, throwable) -> banUser(guild, user, deletionDays, reason)
|
.exceptionally(throwable -> {
|
||||||
.thenCompose(unused1 -> sendBanLogMessage(banLog, guild.getIdLong()))
|
result[0] = BanResult.NOTIFICATION_FAILED;
|
||||||
.thenAccept(unused1 -> {
|
return null;
|
||||||
if(throwable != null) {
|
})
|
||||||
returningFuture.complete(BanResult.NOTIFICATION_FAILED);
|
.thenCompose(unused -> banUser(guild, user, deletionDays, reason))
|
||||||
} else {
|
.thenCompose(unused -> sendBanLogMessage(banLog, guild.getIdLong()))
|
||||||
returningFuture.complete(BanResult.SUCCESSFUL);
|
.thenAccept(banLogMessage -> self.evaluateAndStoreInfraction(user, guild, reason, banningMember, banLogMessage, deletionDays))
|
||||||
}
|
.thenApply(unused -> result[0]);
|
||||||
}));
|
}
|
||||||
return returningFuture;
|
|
||||||
|
@Transactional
|
||||||
|
public CompletableFuture<Long> evaluateAndStoreInfraction(User user, Guild guild, String reason, Member banningMember, Message banLogMessage, Integer deletionDays) {
|
||||||
|
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 banningUser = userInServerManagementService.loadOrCreateUser(banningMember);
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put(INFRACTION_PARAMETER_DELETION_DAYS_KEY, deletionDays.toString());
|
||||||
|
return infractionService.createInfractionWithNotification(bannedUser, infractionPoints, BAN_INFRACTION_TYPE, reason, banningUser, parameters, banLogMessage)
|
||||||
|
.thenApply(Infraction::getId);
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> sendBanNotification(User user, String reason, Guild guild) {
|
private CompletableFuture<Void> sendBanNotification(User user, String reason, Guild guild) {
|
||||||
@@ -102,10 +136,15 @@ public class BanServiceBean implements BanService {
|
|||||||
.thenCompose(unused -> unbanUser(guild, user));
|
.thenCompose(unused -> unbanUser(guild, user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> sendBanLogMessage(BanLog banLog, Long guildId) {
|
public CompletableFuture<Message> sendBanLogMessage(BanLog banLog, Long guildId) {
|
||||||
MessageToSend banLogMessage = templateService.renderEmbedTemplate(BAN_LOG_TEMPLATE, banLog, guildId);
|
MessageToSend banLogMessage = renderBanMessage(banLog, guildId);
|
||||||
log.debug("Sending ban log message in guild {}.", guildId);
|
log.debug("Sending ban log message in guild {}.", guildId);
|
||||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, guildId));
|
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(banLogMessage, ModerationPostTarget.BAN_LOG, guildId);
|
||||||
|
return FutureUtils.toSingleFutureGeneric(messageFutures).thenApply(unused -> messageFutures.get(0).join());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageToSend renderBanMessage(BanLog banLog, Long guildId) {
|
||||||
|
return templateService.renderEmbedTemplate(BAN_LOG_TEMPLATE, banLog, guildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> sendUnBanLogMessage(UnBanLog banLog, Long guildId, String template) {
|
public CompletableFuture<Void> sendUnBanLogMessage(UnBanLog banLog, Long guildId, String template) {
|
||||||
|
|||||||
@@ -1,30 +1,36 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service;
|
package dev.sheldan.abstracto.moderation.service;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.core.Prioritized;
|
||||||
|
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
|
||||||
|
import dev.sheldan.abstracto.core.listener.ListenerService;
|
||||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
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.MemberDisplay;
|
||||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||||
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
|
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.InfractionFeatureConfig;
|
import dev.sheldan.abstracto.moderation.config.feature.InfractionFeatureConfig;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.InfractionPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.InfractionPostTarget;
|
||||||
|
import dev.sheldan.abstracto.moderation.listener.InfractionUpdatedDescriptionListener;
|
||||||
import dev.sheldan.abstracto.moderation.listener.manager.InfractionLevelChangedListenerManager;
|
import dev.sheldan.abstracto.moderation.listener.manager.InfractionLevelChangedListenerManager;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.listener.InfractionDescriptionEventModel;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.InfractionLevelChangeModel;
|
import dev.sheldan.abstracto.moderation.model.template.InfractionLevelChangeModel;
|
||||||
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
import dev.sheldan.abstracto.moderation.service.management.InfractionManagementService;
|
||||||
|
import dev.sheldan.abstracto.moderation.service.management.InfractionParameterManagementService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.util.Pair;
|
import org.springframework.data.util.Pair;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -35,9 +41,6 @@ public class InfractionServiceBean implements InfractionService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private InfractionManagementService infractionManagementService;
|
private InfractionManagementService infractionManagementService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FeatureFlagService featureFlagService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConfigService configService;
|
private ConfigService configService;
|
||||||
|
|
||||||
@@ -56,6 +59,15 @@ public class InfractionServiceBean implements InfractionService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private InfractionLevelChangedListenerManager infractionLevelChangedListenerManager;
|
private InfractionLevelChangedListenerManager infractionLevelChangedListenerManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionParameterManagementService infractionParameterManagementService;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<InfractionUpdatedDescriptionListener> infractionDescriptionListeners;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ListenerService listenerService;
|
||||||
|
|
||||||
private static final String INFRACTION_NOTIFICATION_TEMPLATE_KEY = "infraction_level_notification";
|
private static final String INFRACTION_NOTIFICATION_TEMPLATE_KEY = "infraction_level_notification";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -74,15 +86,31 @@ public class InfractionServiceBean implements InfractionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Infraction> createInfractionWithNotification(AUserInAServer aUserInAServer, Long points) {
|
public CompletableFuture<Infraction> createInfractionWithNotification(AUserInAServer target, Long points, String type, String description, AUserInAServer creator, Map<String, String> parameters, Message message) {
|
||||||
Infraction createdInfraction = infractionManagementService.createInfraction(aUserInAServer, points);
|
Infraction createdInfraction = infractionManagementService.createInfraction(target, points, type, description, creator, message);
|
||||||
|
parameters.forEach((key, value) -> infractionParameterManagementService.createInfractionParameter(createdInfraction, key, value));
|
||||||
Long infractionId = createdInfraction.getId();
|
Long infractionId = createdInfraction.getId();
|
||||||
return createInfractionNotification(aUserInAServer, points)
|
return createInfractionNotification(target, points, type, description)
|
||||||
.thenApply(aBoolean -> self.reloadInfraction(infractionId));
|
.thenApply(avoid -> self.reloadInfraction(infractionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> createInfractionNotification(AUserInAServer aUserInAServer, Long points) {
|
public CompletableFuture<Infraction> createInfractionWithNotification(AUserInAServer target, Long points, String type, String description, AUserInAServer creator, Map<String, String> parameters) {
|
||||||
|
return createInfractionWithNotification(target, points, type, description, creator, new HashMap<>(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Infraction> createInfractionWithNotification(AUserInAServer target, Long points, String type, String description, AUserInAServer creator, Message logMessage) {
|
||||||
|
return createInfractionWithNotification(target, points, type, description, creator, new HashMap<>(), logMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Infraction> createInfractionWithNotification(AUserInAServer target, Long points, String type, String description, AUserInAServer creator) {
|
||||||
|
return createInfractionWithNotification(target, points, type, description, creator, new HashMap<>(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> createInfractionNotification(AUserInAServer aUserInAServer, Long points, String type, String description) {
|
||||||
Long serverId = aUserInAServer.getServerReference().getId();
|
Long serverId = aUserInAServer.getServerReference().getId();
|
||||||
Long currentPoints = getActiveInfractionPointsForUser(aUserInAServer);
|
Long currentPoints = getActiveInfractionPointsForUser(aUserInAServer);
|
||||||
Long newPoints = currentPoints + points;
|
Long newPoints = currentPoints + points;
|
||||||
@@ -95,6 +123,8 @@ public class InfractionServiceBean implements InfractionService {
|
|||||||
.member(MemberDisplay.fromAUserInAServer(aUserInAServer))
|
.member(MemberDisplay.fromAUserInAServer(aUserInAServer))
|
||||||
.newLevel(newLevel)
|
.newLevel(newLevel)
|
||||||
.oldLevel(oldLevel)
|
.oldLevel(oldLevel)
|
||||||
|
.type(type)
|
||||||
|
.description(description)
|
||||||
.oldPoints(currentPoints)
|
.oldPoints(currentPoints)
|
||||||
.newPoints(newPoints)
|
.newPoints(newPoints)
|
||||||
.build();
|
.build();
|
||||||
@@ -107,6 +137,38 @@ public class InfractionServiceBean implements InfractionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> editInfraction(Long infractionId, String newReason, Long serverId) {
|
||||||
|
Infraction infraction = infractionManagementService.loadInfraction(infractionId);
|
||||||
|
if(!infraction.getServer().getId().equals(serverId)) {
|
||||||
|
throw new EntityGuildMismatchException();
|
||||||
|
}
|
||||||
|
infraction.setDescription(newReason);
|
||||||
|
return notifyInfractionListeners(infraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Void> notifyInfractionListeners(Infraction infraction) {
|
||||||
|
InfractionDescriptionEventModel model = getInfractionDescriptionModel(infraction);
|
||||||
|
return infractionDescriptionListeners
|
||||||
|
.stream()
|
||||||
|
.filter(listener -> listener.handlesEvent(model))
|
||||||
|
.max(Comparator.comparing(Prioritized::getPriority))
|
||||||
|
.map(listener -> listenerService.executeAsyncFeatureAwareListener(listener, model))
|
||||||
|
.orElse(CompletableFuture.completedFuture(null))
|
||||||
|
.thenApply(defaultListenerResult -> null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfractionDescriptionEventModel getInfractionDescriptionModel(Infraction infraction) {
|
||||||
|
return InfractionDescriptionEventModel
|
||||||
|
.builder()
|
||||||
|
.infractionId(infraction.getId())
|
||||||
|
.newDescription(infraction.getDescription())
|
||||||
|
.userId(infraction.getUser().getUserReference().getId())
|
||||||
|
.serverId(infraction.getServer().getId())
|
||||||
|
.type(infraction.getType())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Infraction reloadInfraction(Long infractionId) {
|
public Infraction reloadInfraction(Long infractionId) {
|
||||||
return infractionManagementService.loadInfraction(infractionId);
|
return infractionManagementService.loadInfraction(infractionId);
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service;
|
package dev.sheldan.abstracto.moderation.service;
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||||
|
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureConfig;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.ModerationPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.ModerationPostTarget;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -27,18 +36,47 @@ public class KickServiceBean implements KickService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PostTargetService postTargetService;
|
private PostTargetService postTargetService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FeatureFlagService featureFlagService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigService configService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionService infractionService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private KickServiceBean self;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> kickMember(Member member, String reason, KickLogModel kickLogModel) {
|
public CompletableFuture<Void> kickMember(Member member, String reason, KickLogModel kickLogModel) {
|
||||||
Guild guild = member.getGuild();
|
Guild guild = member.getGuild();
|
||||||
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), guild.getIdLong());
|
log.info("Kicking user {} from guild {}", member.getUser().getIdLong(), guild.getIdLong());
|
||||||
CompletableFuture<Void> kickFuture = guild.kick(member, reason).submit();
|
CompletableFuture<Void> kickFuture = guild.kick(member, reason).submit();
|
||||||
CompletableFuture<Void> logFuture = this.sendKickLog(kickLogModel);
|
CompletableFuture<Message> logFuture = this.sendKickLog(kickLogModel);
|
||||||
return CompletableFuture.allOf(kickFuture, logFuture);
|
return CompletableFuture.allOf(kickFuture, logFuture)
|
||||||
|
.thenAccept(unused -> self.storeInfraction(member, reason, kickLogModel, guild, logFuture.join()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> sendKickLog(KickLogModel kickLogModel) {
|
@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());
|
||||||
|
AUserInAServer kickedUser = userInServerManagementService.loadOrCreateUser(member);
|
||||||
|
AUserInAServer kickingUser = userInServerManagementService.loadOrCreateUser(kickLogModel.getMember());
|
||||||
|
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());
|
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel, kickLogModel.getGuild().getIdLong());
|
||||||
log.debug("Sending kick log message in guild {}.", kickLogModel.getGuild().getIdLong());
|
log.debug("Sending kick log message in guild {}.", kickLogModel.getGuild().getIdLong());
|
||||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getGuild().getIdLong()));
|
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, kickLogModel.getGuild().getIdLong());
|
||||||
|
return FutureUtils.toSingleFutureGeneric(messageFutures).thenApply(unused -> messageFutures.get(0).join());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.moderation.service;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
||||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
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.AChannel;
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
@@ -10,25 +10,27 @@ import dev.sheldan.abstracto.core.service.*;
|
|||||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
|
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.FutureUtils;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.mode.MutingMode;
|
import dev.sheldan.abstracto.moderation.config.feature.MutingFeatureConfig;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||||
import dev.sheldan.abstracto.moderation.exception.MuteRoleNotSetupException;
|
|
||||||
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.MuteRole;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
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.MuteNotification;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.UnMuteLog;
|
import dev.sheldan.abstracto.moderation.model.template.command.UnMuteLog;
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
|
|
||||||
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.*;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -45,12 +47,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class MuteServiceBean implements MuteService {
|
public class MuteServiceBean implements MuteService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MuteRoleManagementService muteRoleManagementService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RoleService roleService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserInServerManagementService userInServerManagementService;
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
@@ -91,51 +87,38 @@ public class MuteServiceBean implements MuteService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ServerManagementService serverManagementService;
|
private ServerManagementService serverManagementService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FeatureModeService featureModeService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ChannelService channelService;
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FeatureFlagService featureFlagService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigService configService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionService infractionService;
|
||||||
|
|
||||||
public static final String MUTE_LOG_TEMPLATE = "mute_log";
|
public static final String MUTE_LOG_TEMPLATE = "mute_log";
|
||||||
public static final String UN_MUTE_LOG_TEMPLATE = "unmute_log";
|
|
||||||
public static final String MUTE_NOTIFICATION_TEMPLATE = "mute_notification";
|
public static final String MUTE_NOTIFICATION_TEMPLATE = "mute_notification";
|
||||||
public static final String MUTE_COUNTER_KEY = "MUTES";
|
public static final String MUTE_COUNTER_KEY = "MUTES";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> muteMember(Member memberToMute, Member mutingMember, String reason, Instant unMuteDate, ServerChannelMessage message) {
|
public CompletableFuture<Void> muteMember(Member memberToMute, String reason, Instant unMuteDate, Long channelId) {
|
||||||
FullUserInServer mutedUser = FullUserInServer
|
FullUserInServer mutedUser = FullUserInServer
|
||||||
.builder()
|
.builder()
|
||||||
.aUserInAServer(userInServerManagementService.loadOrCreateUser(memberToMute))
|
.aUserInAServer(userInServerManagementService.loadOrCreateUser(memberToMute))
|
||||||
.member(memberToMute)
|
.member(memberToMute)
|
||||||
.build();
|
.build();
|
||||||
|
return muteUserInServer(mutedUser, reason, unMuteDate, channelId);
|
||||||
FullUserInServer mutingUser = FullUserInServer
|
|
||||||
.builder()
|
|
||||||
.aUserInAServer(userInServerManagementService.loadOrCreateUser(mutingMember))
|
|
||||||
.member(mutingMember)
|
|
||||||
.build();
|
|
||||||
return muteUserInServer(mutedUser, mutingUser, reason, unMuteDate, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> muteUserInServer(FullUserInServer userBeingMuted, FullUserInServer userMuting, String reason, Instant unMuteDate, ServerChannelMessage message) {
|
public CompletableFuture<Void> muteUserInServer(FullUserInServer userBeingMuted, String reason, Instant unMuteDate, Long channelId) {
|
||||||
AServer serverBeingMutedIn = userBeingMuted.getAUserInAServer().getServerReference();
|
|
||||||
if(!muteRoleManagementService.muteRoleForServerExists(serverBeingMutedIn)) {
|
|
||||||
log.error("Mute role for server {} has not been setup.", serverBeingMutedIn.getId());
|
|
||||||
throw new MuteRoleNotSetupException();
|
|
||||||
}
|
|
||||||
Member memberBeingMuted = userBeingMuted.getMember();
|
Member memberBeingMuted = userBeingMuted.getMember();
|
||||||
log.info("User {} mutes user {} in server {} until {}",
|
|
||||||
memberBeingMuted.getIdLong(), message.getServerId(), userMuting.getMember().getIdLong(), unMuteDate);
|
|
||||||
if(message.getMessageId() != null) {
|
|
||||||
log.info("because of message {} in channel {} in server {}", message.getMessageId(), message.getChannelId(), message.getServerId());
|
|
||||||
} else {
|
|
||||||
log.info("This mute was not triggered by a message.");
|
|
||||||
}
|
|
||||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||||
AUserInAServer userInServerBeingMuted = userBeingMuted.getAUserInAServer();
|
|
||||||
futures.add(applyMuteRole(userInServerBeingMuted));
|
futures.add(memberService.timeoutUser(userBeingMuted.getMember(), unMuteDate));
|
||||||
Guild guild = memberBeingMuted.getGuild();
|
Guild guild = memberBeingMuted.getGuild();
|
||||||
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
|
if(memberBeingMuted.getVoiceState() != null && memberBeingMuted.getVoiceState().getChannel() != null) {
|
||||||
futures.add(guild.kickVoiceMember(memberBeingMuted).submit());
|
futures.add(guild.kickVoiceMember(memberBeingMuted).submit());
|
||||||
@@ -146,17 +129,18 @@ public class MuteServiceBean implements MuteService {
|
|||||||
.reason(reason)
|
.reason(reason)
|
||||||
.serverName(guild.getName())
|
.serverName(guild.getName())
|
||||||
.build();
|
.build();
|
||||||
futures.add(sendMuteNotification(message, memberBeingMuted, muteNotification));
|
futures.add(sendMuteNotification(memberBeingMuted, muteNotification, channelId));
|
||||||
return FutureUtils.toSingleFutureGeneric(futures);
|
return FutureUtils.toSingleFutureGeneric(futures);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> sendMuteNotification(ServerChannelMessage message, Member memberBeingMuted, MuteNotification muteNotification) {
|
private CompletableFuture<Void> sendMuteNotification(Member memberBeingMuted, MuteNotification muteNotification, Long channelId) {
|
||||||
log.info("Notifying the user about the mute.");
|
log.info("Notifying the user about the mute.");
|
||||||
CompletableFuture<Void> notificationFuture = new CompletableFuture<>();
|
CompletableFuture<Void> notificationFuture = new CompletableFuture<>();
|
||||||
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification, message.getServerId());
|
Long guildId = memberBeingMuted.getGuild().getIdLong();
|
||||||
|
String muteNotificationMessage = templateService.renderTemplate(MUTE_NOTIFICATION_TEMPLATE, muteNotification, guildId);
|
||||||
CompletableFuture<Message> messageCompletableFuture = messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage);
|
CompletableFuture<Message> messageCompletableFuture = messageService.sendMessageToUser(memberBeingMuted.getUser(), muteNotificationMessage);
|
||||||
messageCompletableFuture.exceptionally(throwable -> {
|
messageCompletableFuture.exceptionally(throwable -> {
|
||||||
GuildMessageChannel feedBackChannel = channelService.getMessageChannelFromServer(message.getServerId(), message.getChannelId());
|
GuildMessageChannel feedBackChannel = channelService.getMessageChannelFromServer(guildId, channelId);
|
||||||
channelService.sendTextToChannel(throwable.getMessage(), feedBackChannel).whenComplete((exceptionMessage, innerThrowable) -> {
|
channelService.sendTextToChannel(throwable.getMessage(), feedBackChannel).whenComplete((exceptionMessage, innerThrowable) -> {
|
||||||
notificationFuture.complete(null);
|
notificationFuture.complete(null);
|
||||||
log.info("Successfully notified user {} in server {} about mute.", memberBeingMuted.getId(), memberBeingMuted.getGuild().getId());
|
log.info("Successfully notified user {} in server {} about mute.", memberBeingMuted.getId(), memberBeingMuted.getGuild().getId());
|
||||||
@@ -172,23 +156,16 @@ public class MuteServiceBean implements MuteService {
|
|||||||
return notificationFuture;
|
return notificationFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMuteObject(MuteContext muteContext, String triggerKey) {
|
private void createMuteObject(MuteContext muteContext, String triggerKey, Long infractionId) {
|
||||||
AChannel channel = channelManagementService.loadChannel(muteContext.getContext().getChannelId());
|
AChannel channel = channelManagementService.loadChannel(muteContext.getChannelId());
|
||||||
AServerAChannelMessage origin = AServerAChannelMessage
|
AServerAChannelMessage origin = AServerAChannelMessage
|
||||||
.builder()
|
.builder()
|
||||||
.channel(channel)
|
.channel(channel)
|
||||||
.server(channel.getServer())
|
.server(channel.getServer())
|
||||||
.messageId(muteContext.getContext().getMessageId())
|
|
||||||
.build();
|
.build();
|
||||||
AUserInAServer userInServerBeingMuted = userInServerManagementService.loadOrCreateUser(muteContext.getMutedUser());
|
AUserInAServer userInServerBeingMuted = userInServerManagementService.loadOrCreateUser(muteContext.getMutedUser());
|
||||||
AUserInAServer userInServerMuting = userInServerManagementService.loadOrCreateUser(muteContext.getMutingUser());
|
AUserInAServer userInServerMuting = userInServerManagementService.loadOrCreateUser(muteContext.getMutingUser());
|
||||||
muteManagementService.createMute(userInServerBeingMuted, userInServerMuting, muteContext.getReason(), muteContext.getMuteTargetDate(), origin, triggerKey, muteContext.getMuteId());
|
muteManagementService.createMute(userInServerBeingMuted, userInServerMuting, muteContext.getReason(), muteContext.getMuteTargetDate(), origin, triggerKey, muteContext.getMuteId(), infractionId);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Void> applyMuteRole(AUserInAServer aUserInAServer) {
|
|
||||||
MuteRole muteRole = muteRoleManagementService.retrieveMuteRoleForServer(aUserInAServer.getServerReference());
|
|
||||||
return roleService.addRoleToUserAsync(aUserInAServer, muteRole.getRole());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -217,6 +194,7 @@ public class MuteServiceBean implements MuteService {
|
|||||||
@Override
|
@Override
|
||||||
public void cancelUnMuteJob(Mute mute) {
|
public void cancelUnMuteJob(Mute mute) {
|
||||||
if(mute.getTriggerKey() != null) {
|
if(mute.getTriggerKey() != null) {
|
||||||
|
log.info("Cancelling un-mute job for mute {} in server {}.", mute.getMuteId().getId(), mute.getServer().getId());
|
||||||
schedulerService.stopTrigger(mute.getTriggerKey());
|
schedulerService.stopTrigger(mute.getTriggerKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,107 +202,116 @@ public class MuteServiceBean implements MuteService {
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> muteMemberWithLog(MuteContext context) {
|
public CompletableFuture<Void> muteMemberWithLog(MuteContext context) {
|
||||||
log.debug("Muting member {} in server {}.", context.getMutedUser().getId(), context.getMutedUser().getGuild().getId());
|
log.debug("Muting member {} in server {}.", context.getMutedUser().getId(), context.getMutedUser().getGuild().getId());
|
||||||
AServer server = serverManagementService.loadOrCreate(context.getContext().getServerId());
|
AServer server = serverManagementService.loadOrCreate(context.getMutedUser().getGuild().getIdLong());
|
||||||
Long nextCounterValue = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
|
Long nextCounterValue = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
|
||||||
context.setMuteId(nextCounterValue);
|
context.setMuteId(nextCounterValue);
|
||||||
CompletableFuture<Void> mutingFuture = muteMember(context.getMutedUser(), context.getMutingUser(), context.getReason(), context.getMuteTargetDate(), context.getContext());
|
return muteMember(context.getMutedUser(), context.getReason(), context.getMuteTargetDate(), context.getChannelId())
|
||||||
CompletableFuture<Void> muteLogFuture = sendMuteLog(context, server);
|
.thenCompose(unused -> self.sendMuteLog(context))
|
||||||
return CompletableFuture.allOf(mutingFuture, muteLogFuture).thenAccept(aVoid ->
|
.thenCompose(logMessage -> self.evaluateAndStoreInfraction(context, logMessage))
|
||||||
self.persistMute(context)
|
.thenAccept(infractionId -> self.persistMute(context, infractionId));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void persistMute(MuteContext context) {
|
public CompletableFuture<Long> evaluateAndStoreInfraction(MuteContext context, Message logMessage) {
|
||||||
String triggerKey = startUnMuteJobFor(context.getMuteTargetDate(), context.getMuteId(), context.getContext().getServerId());
|
Guild guild = context.getMutedUser().getGuild();
|
||||||
createMuteObject(context, triggerKey);
|
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());
|
||||||
|
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)
|
||||||
|
.thenApply(Infraction::getId);
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> sendMuteLog(MuteContext muteLogModel, AServer server) {
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CompletableFuture<Message> sendMuteLog(MuteContext muteLogModel) {
|
||||||
|
MuteListenerModel model = MuteListenerModel
|
||||||
|
.builder()
|
||||||
|
.mutedUser(muteLogModel.getMutedUser())
|
||||||
|
.mutingUser(muteLogModel.getMutingUser())
|
||||||
|
.channelId(muteLogModel.getChannelId())
|
||||||
|
.oldMuteTargetDate(null)
|
||||||
|
.muteTargetDate(muteLogModel.getMuteTargetDate())
|
||||||
|
.reason(muteLogModel.getReason())
|
||||||
|
.build();
|
||||||
log.debug("Sending mute log to the mute post target.");
|
log.debug("Sending mute log to the mute post target.");
|
||||||
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, muteLogModel, server.getId());
|
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, muteLogModel.getMutedUser().getIdLong());
|
||||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getContext().getServerId()));
|
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, muteLogModel.getMutedUser().getGuild().getIdLong());
|
||||||
|
return FutureUtils.toSingleFutureGeneric(futures).thenApply(unused -> futures.get(0).join());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> sendUnMuteLogMessage(UnMuteLog muteLogModel, AServer server) {
|
private CompletableFuture<Void> sendUnMuteLogMessage(UnMuteLog muteLogModel, AServer server) {
|
||||||
log.debug("Sending unMute log for mute {} to the mute posttarget in server {}", muteLogModel.getMute().getMuteId().getId(), server.getId());
|
MuteListenerModel model = MuteListenerModel
|
||||||
MessageToSend message = templateService.renderEmbedTemplate(UN_MUTE_LOG_TEMPLATE, muteLogModel, server.getId());
|
.builder()
|
||||||
|
.mutedUser(muteLogModel.getUnMutedUser())
|
||||||
|
.mutingUser(muteLogModel.getMutingUser())
|
||||||
|
.oldMuteTargetDate(muteLogModel.getMute() != null ? muteLogModel.getMute().getMuteTargetDate() : null)
|
||||||
|
.muteTargetDate(null)
|
||||||
|
.build();
|
||||||
|
if(muteLogModel.getMute() != null) {
|
||||||
|
log.debug("Sending unMute log for mute {} to the mute posttarget in server {}", muteLogModel.getMute().getMuteId().getId(), server.getId());
|
||||||
|
}
|
||||||
|
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, server.getId());
|
||||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, server.getId()));
|
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, server.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CompletableFuture<Void> unMuteUser(AUserInAServer aUserInAServer) {
|
public CompletableFuture<Void> unMuteUser(AUserInAServer userToUnmute, Member unMutingMember) {
|
||||||
if(!muteManagementService.hasActiveMute(aUserInAServer)) {
|
boolean muteActive = muteManagementService.hasActiveMute(userToUnmute);
|
||||||
throw new NoMuteFoundException();
|
if(!muteActive) {
|
||||||
}
|
CompletableFuture<Member> unMutedMemberFuture = memberService.retrieveMemberInServer(ServerUser.fromAUserInAServer(userToUnmute));
|
||||||
Mute mute = muteManagementService.getAMuteOf(aUserInAServer);
|
return unMutedMemberFuture
|
||||||
Long muteId = mute.getMuteId().getId();
|
.thenCompose(member -> memberService.removeTimeout(member))
|
||||||
CompletableFuture<Member> mutingMemberFuture = memberService.getMemberInServerAsync(mute.getMutingUser());
|
.thenCompose(unused -> self.sendUnmuteLog(null, unMutingMember.getGuild(), unMutedMemberFuture.join(), unMutingMember));
|
||||||
CompletableFuture<Member> mutedMemberFuture = memberService.getMemberInServerAsync(mute.getMutedUser());
|
|
||||||
Guild guild = guildService.getGuildById(mute.getMuteId().getServerId());
|
|
||||||
return endMute(mute, false).thenCompose(unused ->
|
|
||||||
CompletableFuture.allOf(mutingMemberFuture, mutedMemberFuture)
|
|
||||||
).thenCompose(unused -> self.sendUnMuteLogForManualUnMute(muteId, mutingMemberFuture, mutedMemberFuture, guild));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public CompletableFuture<Void> sendUnMuteLogForManualUnMute(Long muteId, CompletableFuture<Member> mutingMemberFuture, CompletableFuture<Member> mutedMemberFuture, Guild guild) {
|
|
||||||
CompletableFuture<Void> completableFuture;
|
|
||||||
if(featureModeService.featureModeActive(ModerationFeatureDefinition.MUTING, guild.getIdLong(), MutingMode.MANUAL_UN_MUTE_LOGGING)) {
|
|
||||||
completableFuture = self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture);
|
|
||||||
log.info("Sending un mute notification for manual un mute for mute {} in server {}.", muteId, guild.getIdLong());
|
|
||||||
} else {
|
} else {
|
||||||
completableFuture = CompletableFuture.completedFuture(null);
|
Mute mute = muteManagementService.getAMuteOf(userToUnmute);
|
||||||
log.info("Not sending unMute log, because feature mode {} in feature {} has been disabled for server {}.", MutingMode.MANUAL_UN_MUTE_LOGGING, ModerationFeatureDefinition.WARNING, guild.getIdLong());
|
return endMute(mute);
|
||||||
}
|
}
|
||||||
return completableFuture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> endMute(Mute mute, Boolean sendNotification) {
|
public CompletableFuture<Void> endMute(Mute mute) {
|
||||||
if(mute.getMuteEnded()) {
|
if(mute.getMuteEnded()) {
|
||||||
log.info("Mute {} in server {} has already ended. Not unmuting.", mute.getMuteId().getId(), mute.getMuteId().getServerId());
|
log.info("Mute {} in server {} has already ended. Not unmuting.", mute.getMuteId().getId(), mute.getMuteId().getServerId());
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
Long muteId = mute.getMuteId().getId();
|
Long muteId = mute.getMuteId().getId();
|
||||||
Long serverId = mute.getMuteId().getServerId();
|
Guild guild = guildService.getGuildById(mute.getMuteId().getServerId());
|
||||||
AServer mutingServer = mute.getServer();
|
AServer mutingServer = mute.getServer();
|
||||||
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
|
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
|
||||||
MuteRole muteRole = muteRoleManagementService.retrieveMuteRoleForServer(mutingServer);
|
|
||||||
log.debug("Using the mute role {} mapping to role {}", muteRole.getId(), muteRole.getRole().getId());
|
|
||||||
Guild guild = guildService.getGuildById(mutingServer.getId());
|
|
||||||
CompletableFuture<Void> roleRemovalFuture = roleService.removeRoleFromUserAsync(mute.getMutedUser(), muteRole.getRole());
|
|
||||||
CompletableFuture<Member> mutingMemberFuture = memberService.getMemberInServerAsync(mute.getMutingUser());
|
|
||||||
CompletableFuture<Member> mutedMemberFuture = memberService.getMemberInServerAsync(mute.getMutedUser());
|
CompletableFuture<Member> mutedMemberFuture = memberService.getMemberInServerAsync(mute.getMutedUser());
|
||||||
CompletableFuture<Void> finalFuture = new CompletableFuture<>();
|
CompletableFuture<Member> mutingMemberFuture = memberService.getMemberInServerAsync(mute.getMutingUser());
|
||||||
CompletableFuture.allOf(mutingMemberFuture, mutedMemberFuture, roleRemovalFuture, mutingMemberFuture, mutedMemberFuture).handle((aVoid, throwable) -> {
|
return CompletableFuture.allOf(mutedMemberFuture, mutingMemberFuture)
|
||||||
if(sendNotification) {
|
.thenAccept(member -> memberService.removeTimeout(mutedMemberFuture.join()))
|
||||||
self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture).thenAccept(aVoid1 ->
|
.thenCompose(unused -> self.sendUnmuteLog(muteId, guild, mutingMemberFuture, mutedMemberFuture));
|
||||||
finalFuture.complete(null)
|
|
||||||
).exceptionally(throwable1 -> {
|
|
||||||
log.error("Unmute log failed to send for mute {} in server {}.", muteId, serverId, throwable1);
|
|
||||||
finalFuture.completeExceptionally(null);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
finalFuture.complete(null);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}).exceptionally(throwable -> {
|
|
||||||
finalFuture.completeExceptionally(throwable);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
return finalFuture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, CompletableFuture<Member> mutingMemberFuture, CompletableFuture<Member> mutedMemberFuture) {
|
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, CompletableFuture<Member> mutingMemberFuture, CompletableFuture<Member> mutedMemberFuture) {
|
||||||
Mute mute = muteManagementService.findMute(muteId, guild.getIdLong());
|
|
||||||
AServer mutingServer = serverManagementService.loadServer(guild.getIdLong());
|
|
||||||
Member mutingMember = !mutingMemberFuture.isCompletedExceptionally() ? mutingMemberFuture.join() : null;
|
Member mutingMember = !mutingMemberFuture.isCompletedExceptionally() ? mutingMemberFuture.join() : null;
|
||||||
Member mutedMember = !mutedMemberFuture.isCompletedExceptionally() ? mutedMemberFuture.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) {
|
||||||
|
Mute mute = null;
|
||||||
|
if(muteId != null) {
|
||||||
|
mute = muteManagementService.findMute(muteId, guild.getIdLong());
|
||||||
|
}
|
||||||
|
AServer mutingServer = serverManagementService.loadServer(guild.getIdLong());
|
||||||
UnMuteLog unMuteLog = UnMuteLog
|
UnMuteLog unMuteLog = UnMuteLog
|
||||||
.builder()
|
.builder()
|
||||||
.mute(mute)
|
.mute(mute)
|
||||||
@@ -333,9 +320,11 @@ public class MuteServiceBean implements MuteService {
|
|||||||
.guild(guild)
|
.guild(guild)
|
||||||
.build();
|
.build();
|
||||||
CompletableFuture<Void> notificationFuture = sendUnMuteLogMessage(unMuteLog, mutingServer);
|
CompletableFuture<Void> notificationFuture = sendUnMuteLogMessage(unMuteLog, mutingServer);
|
||||||
return CompletableFuture.allOf(notificationFuture).thenAccept(aVoid ->
|
return CompletableFuture.allOf(notificationFuture).thenAccept(aVoid -> {
|
||||||
self.endMuteInDatabase(muteId, guild.getIdLong())
|
if(muteId != null) {
|
||||||
);
|
self.endMuteInDatabase(muteId, guild.getIdLong());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -344,7 +333,6 @@ public class MuteServiceBean implements MuteService {
|
|||||||
muteOptional.ifPresent(mute ->
|
muteOptional.ifPresent(mute ->
|
||||||
completelyUnMuteUser(mute.getMutedUser())
|
completelyUnMuteUser(mute.getMutedUser())
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -353,7 +341,7 @@ public class MuteServiceBean implements MuteService {
|
|||||||
log.info("UnMuting the mute {} in server {}", muteId, serverId);
|
log.info("UnMuting the mute {} in server {}", muteId, serverId);
|
||||||
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
|
Optional<Mute> muteOptional = muteManagementService.findMuteOptional(muteId, serverId);
|
||||||
if(muteOptional.isPresent()) {
|
if(muteOptional.isPresent()) {
|
||||||
return endMute(muteOptional.get(), true);
|
return endMute(muteOptional.get());
|
||||||
} else {
|
} else {
|
||||||
throw new NoMuteFoundException();
|
throw new NoMuteFoundException();
|
||||||
}
|
}
|
||||||
@@ -375,10 +363,4 @@ public class MuteServiceBean implements MuteService {
|
|||||||
completelyUnMuteUser(userInServerManagementService.loadOrCreateUser(member));
|
completelyUnMuteUser(userInServerManagementService.loadOrCreateUser(member));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Void> muteMemberWithoutContext(Member member) {
|
|
||||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
|
|
||||||
return applyMuteRole(aUserInAServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ package dev.sheldan.abstracto.moderation.service;
|
|||||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
import dev.sheldan.abstracto.core.service.*;
|
||||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.mode.ReportReactionMode;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.ReactionReportPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.ReactionReportPostTarget;
|
||||||
|
import dev.sheldan.abstracto.moderation.listener.manager.ReportMessageCreatedListenerManager;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.ModerationUser;
|
import dev.sheldan.abstracto.moderation.model.database.ModerationUser;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.ReactionReport;
|
import dev.sheldan.abstracto.moderation.model.database.ReactionReport;
|
||||||
import dev.sheldan.abstracto.moderation.model.template.listener.ReportReactionNotificationModel;
|
import dev.sheldan.abstracto.moderation.model.template.listener.ReportReactionNotificationModel;
|
||||||
@@ -19,7 +20,6 @@ import dev.sheldan.abstracto.moderation.service.management.ReactionReportManagem
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
import net.dv8tion.jda.api.entities.GuildMessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -59,46 +59,60 @@ public class ReactionReportServiceBean implements ReactionReportService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ReactionReportServiceBean self;
|
private ReactionReportServiceBean self;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CacheEntityService cacheEntityService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FeatureModeService featureModeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ReportMessageCreatedListenerManager reportMessageCreatedListenerManager;
|
||||||
|
|
||||||
private static final String REACTION_REPORT_TEMPLATE_KEY = "reactionReport_notification";
|
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";
|
||||||
|
public static final String REACTION_REPORT_COOLDOWN_RESPONSE_TEMPLATE = "reactionReport_cooldown_response";
|
||||||
|
public static final String REACTION_REPORT_OWN_MESSAGE_RESPONSE_TEMPLATE = "reactionReport_own_message_response";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> createReactionReport(CachedMessage reportedMessage, ServerUser reporter) {
|
public CompletableFuture<Void> createReactionReport(CachedMessage reportedMessage, ServerUser reporter, String context) {
|
||||||
AUserInAServer reportedUser = userInServerManagementService.loadOrCreateUser(reportedMessage.getAuthorAsServerUser());
|
AUserInAServer reportedUser = userInServerManagementService.loadOrCreateUser(reportedMessage.getAuthorAsServerUser());
|
||||||
AUserInAServer reportingUser = userInServerManagementService.loadOrCreateUser(reporter);
|
|
||||||
Optional<ModerationUser> moderationUserOptional = moderationUserManagementService.findModerationUser(reportingUser);
|
|
||||||
Long serverId = reporter.getServerId();
|
Long serverId = reporter.getServerId();
|
||||||
|
log.info("User {} in server {} was reported on message {}", reportedMessage.getAuthor().getAuthorId(), serverId, reportedMessage.getMessageId());
|
||||||
Long cooldownSeconds = configService.getLongValueOrConfigDefault(REACTION_REPORT_COOLDOWN, serverId);
|
Long cooldownSeconds = configService.getLongValueOrConfigDefault(REACTION_REPORT_COOLDOWN, serverId);
|
||||||
Duration maxAge = Duration.of(cooldownSeconds, ChronoUnit.SECONDS);
|
Duration maxAge = Duration.of(cooldownSeconds, ChronoUnit.SECONDS);
|
||||||
if(moderationUserOptional.isPresent()) {
|
|
||||||
ModerationUser reporterModerationUser = moderationUserOptional.get();
|
|
||||||
Instant minAllowedReportTime = Instant.now().minus(maxAge);
|
|
||||||
if(reporterModerationUser.getLastReportTimeStamp() != null && reporterModerationUser.getLastReportTimeStamp().isAfter(minAllowedReportTime)) {
|
|
||||||
log.info("User {} in server {} reported user {} within the cooldown. Ignoring.", reporter.getUserId(), serverId, reportedMessage.getAuthor().getAuthorId());
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.info("User {} in server {} reported user {}..", reporter.getUserId(), serverId, reportedMessage.getAuthor().getAuthorId());
|
|
||||||
Optional<ReactionReport> recentReportOptional = reactionReportManagementService.findRecentReactionReportAboutUser(reportedUser, maxAge);
|
Optional<ReactionReport> recentReportOptional = reactionReportManagementService.findRecentReactionReportAboutUser(reportedUser, maxAge);
|
||||||
if(!recentReportOptional.isPresent()) {
|
boolean singularMessage = featureModeService.featureModeActive(ModerationFeatureDefinition.REPORT_REACTIONS, serverId, ReportReactionMode.SINGULAR_MESSAGE);
|
||||||
ReportReactionNotificationModel model = ReportReactionNotificationModel
|
boolean anonym = featureModeService.featureModeActive(ModerationFeatureDefinition.REPORT_REACTIONS, reporter.getServerId(), ReportReactionMode.ANONYMOUS);
|
||||||
.builder()
|
if(recentReportOptional.isPresent() && singularMessage) {
|
||||||
.reportCount(1)
|
|
||||||
.reportedMessage(reportedMessage)
|
|
||||||
.build();
|
|
||||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(REACTION_REPORT_TEMPLATE_KEY, model, serverId);
|
|
||||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, ReactionReportPostTarget.REACTION_REPORTS, serverId);
|
|
||||||
return FutureUtils.toSingleFutureGeneric(messageFutures)
|
|
||||||
.thenAccept(unused -> self.createReactionReportInDb(reportedMessage, messageFutures.get(0).join(), reporter));
|
|
||||||
} else {
|
|
||||||
ReactionReport report = recentReportOptional.get();
|
ReactionReport report = recentReportOptional.get();
|
||||||
log.info("Report is already present in channel {} with message {}. Updating field.", report.getReportChannel().getId(), report.getReportMessageId());
|
log.info("Report is already present in channel {} with message {}. Updating field.", report.getReportChannel().getId(), report.getReportMessageId());
|
||||||
report.setReportCount(report.getReportCount() + 1);
|
report.setReportCount(report.getReportCount() + 1);
|
||||||
GuildMessageChannel reportTextChannel = channelService.getMessageChannelFromServer(serverId, report.getReportChannel().getId());
|
GuildMessageChannel reportTextChannel = channelService.getMessageChannelFromServer(serverId, report.getReportChannel().getId());
|
||||||
return channelService.editFieldValueInMessage(reportTextChannel, report.getReportMessageId(), 0, report.getReportCount().toString())
|
return channelService.editFieldValueInMessage(reportTextChannel, report.getReportMessageId(), 0, report.getReportCount().toString())
|
||||||
.thenAccept(message -> self.updateModerationUserReportCooldown(reporter));
|
.thenAccept(message -> self.updateModerationUserReportCooldown(reporter));
|
||||||
|
} else {
|
||||||
|
ReportReactionNotificationModel model = ReportReactionNotificationModel
|
||||||
|
.builder()
|
||||||
|
.reportCount(1)
|
||||||
|
.context(context)
|
||||||
|
.singularMessage(singularMessage)
|
||||||
|
.reportedMessage(reportedMessage)
|
||||||
|
.build();
|
||||||
|
MessageToSend messageToSend = templateService.renderEmbedTemplate(REACTION_REPORT_TEMPLATE_KEY, model, serverId);
|
||||||
|
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, ReactionReportPostTarget.REACTION_REPORTS, serverId);
|
||||||
|
return FutureUtils.toSingleFutureGeneric(messageFutures)
|
||||||
|
.thenAccept(unused -> reportMessageCreatedListenerManager.sendReportMessageCreatedEvent(reportedMessage, messageFutures.get(0).join(), anonym ? null : reporter))
|
||||||
|
.thenAccept(unused -> self.createReactionReportInDb(reportedMessage, messageFutures.get(0).join(), reporter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> createReactionReport(Message message, ServerUser reporter, String context) {
|
||||||
|
return cacheEntityService.buildCachedMessageFromMessage(message)
|
||||||
|
.thenCompose(cachedMessage -> createReactionReport(cachedMessage, reporter, context));
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void createReactionReportInDb(CachedMessage cachedMessage, Message reportMessage, ServerUser reporter) {
|
public void createReactionReportInDb(CachedMessage cachedMessage, Message reportMessage, ServerUser reporter) {
|
||||||
if(reportMessage == null) {
|
if(reportMessage == null) {
|
||||||
@@ -112,15 +126,35 @@ public class ReactionReportServiceBean implements ReactionReportService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updateModerationUserReportCooldown(ServerUser reporter) {
|
public void updateModerationUserReportCooldown(ServerUser reporter) {
|
||||||
AUserInAServer reporterAUserInServer = userInServerManagementService.loadOrCreateUser(reporter);
|
if(!featureModeService.featureModeActive(ModerationFeatureDefinition.REPORT_REACTIONS, reporter.getServerId(), ReportReactionMode.ANONYMOUS)) {
|
||||||
Optional<ModerationUser> optionalModerationUser = moderationUserManagementService.findModerationUser(reporterAUserInServer);
|
AUserInAServer reporterAUserInServer = userInServerManagementService.loadOrCreateUser(reporter);
|
||||||
Instant reportTimeStamp = Instant.now();
|
Optional<ModerationUser> optionalModerationUser = moderationUserManagementService.findModerationUser(reporterAUserInServer);
|
||||||
if(optionalModerationUser.isPresent()) {
|
Instant reportTimeStamp = Instant.now();
|
||||||
log.info("Updating last report time of user {}.", reporter.getUserId());
|
if(optionalModerationUser.isPresent()) {
|
||||||
optionalModerationUser.get().setLastReportTimeStamp(reportTimeStamp);
|
log.info("Updating last report time of user {}.", reporter.getUserId());
|
||||||
} else {
|
optionalModerationUser.get().setLastReportTimeStamp(reportTimeStamp);
|
||||||
log.info("Creating new moderation user instance for user {} to track report cooldowns.", reporter.getUserId());
|
} else {
|
||||||
moderationUserManagementService.createModerationUserWithReportTimeStamp(reporterAUserInServer, reportTimeStamp);
|
log.info("Creating new moderation user instance for user {} to track report cooldowns.", reporter.getUserId());
|
||||||
|
moderationUserManagementService.createModerationUserWithReportTimeStamp(reporterAUserInServer, reportTimeStamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowedToReport(ServerUser reporter) {
|
||||||
|
Long cooldownSeconds = configService.getLongValueOrConfigDefault(REACTION_REPORT_COOLDOWN, reporter.getServerId());
|
||||||
|
Duration maxAge = Duration.of(cooldownSeconds, ChronoUnit.SECONDS);
|
||||||
|
AUserInAServer reportingUser = userInServerManagementService.loadOrCreateUser(reporter);
|
||||||
|
Optional<ModerationUser> moderationUserOptional = moderationUserManagementService.findModerationUser(reportingUser);
|
||||||
|
if(moderationUserOptional.isPresent()) {
|
||||||
|
ModerationUser reporterModerationUser = moderationUserOptional.get();
|
||||||
|
Instant minAllowedReportTime = Instant
|
||||||
|
.now()
|
||||||
|
.minus(maxAge);
|
||||||
|
if(reporterModerationUser.getLastReportTimeStamp() != null) {
|
||||||
|
return !reporterModerationUser.getLastReportTimeStamp().isAfter(minAllowedReportTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ public class WarnServiceBean implements WarnService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> notifyAndLogFullUserWarning(WarnContext context) {
|
public CompletableFuture<Void> notifyAndLogFullUserWarning(WarnContext context) {
|
||||||
AServer server = serverManagementService.loadOrCreate(context.getGuild().getIdLong());
|
Long serverId = context.getGuild().getIdLong();
|
||||||
Long warningId = counterService.getNextCounterValue(server, WARNINGS_COUNTER_KEY);
|
Long warningId = counterService.getNextCounterValue(serverId, WARNINGS_COUNTER_KEY);
|
||||||
context.setWarnId(warningId);
|
context.setWarnId(warningId);
|
||||||
Member warnedMember = context.getWarnedMember();
|
Member warnedMember = context.getWarnedMember();
|
||||||
Member warningMember = context.getMember();
|
Member warningMember = context.getMember();
|
||||||
@@ -124,29 +124,39 @@ public class WarnServiceBean implements WarnService {
|
|||||||
.warnId(warningId)
|
.warnId(warningId)
|
||||||
.serverName(guild.getName())
|
.serverName(guild.getName())
|
||||||
.build();
|
.build();
|
||||||
Long serverId = server.getId();
|
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification, serverId);
|
||||||
String warnNotificationMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification, server.getId());
|
return messageService.sendMessageToUser(warnedMember.getUser(), warnNotificationMessage)
|
||||||
List<CompletableFuture> futures = new ArrayList<>();
|
.exceptionally(throwable -> {
|
||||||
CompletableFuture<Void> notificationFuture = new CompletableFuture<>();
|
log.warn("Failed to notify user {} of warning {} in guild {}.", warnedMember.getId(), warningId, serverId);
|
||||||
messageService.sendMessageToUser(warnedMember.getUser(), warnNotificationMessage).whenComplete((message, throwable) -> {
|
return null;
|
||||||
if(throwable != null) {
|
})
|
||||||
log.warn("Failed to notify user {} of warning {} in guild {}.", warnedMember.getId(), warningId, serverId);
|
.thenCompose(message -> self.sendWarningLog(context))
|
||||||
}
|
.thenCompose(logMessage -> self.evaluateInfraction(context, logMessage))
|
||||||
notificationFuture.complete(null);
|
.thenAccept(context::setInfractionId);
|
||||||
});
|
}
|
||||||
futures.add(notificationFuture);
|
|
||||||
log.debug("Logging warning for server {}.", server.getId());
|
@Transactional
|
||||||
|
public CompletableFuture<Message> sendWarningLog(WarnContext context) {
|
||||||
|
MessageToSend message = renderMessageModel(context);
|
||||||
|
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, context.getGuild().getIdLong());
|
||||||
|
return FutureUtils.toSingleFutureGeneric(futures).thenCompose(unused -> futures.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CompletableFuture<Long> evaluateInfraction(WarnContext context, Message logMessage) {
|
||||||
|
Long serverId = context.getGuild().getIdLong();
|
||||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||||
Long infractionPoints = configService.getLongValueOrConfigDefault(WarningFeatureConfig.WARN_INFRACTION_POINTS, serverId);
|
Long infractionPoints = configService.getLongValueOrConfigDefault(WarningFeatureConfig.WARN_INFRACTION_POINTS, serverId);
|
||||||
AUserInAServer warnedUser = userInServerManagementService.loadOrCreateUser(warnedMember);
|
AServer server = serverManagementService.loadServer(context.getGuild());
|
||||||
warnedUser.setServerReference(server);
|
AUserInAServer warnedUser = userInServerManagementService.loadOrCreateUser(server, context.getWarnedMember().getIdLong());
|
||||||
futures.add(infractionService.createInfractionWithNotification(warnedUser, infractionPoints)
|
AUserInAServer warningUser = userInServerManagementService.loadOrCreateUser(server, context.getMember().getIdLong());
|
||||||
.thenAccept(infraction -> context.setInfractionId(infraction.getId())));
|
// 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)
|
||||||
|
.thenApply(Infraction::getId);
|
||||||
|
} else {
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
MessageToSend message = templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, context, server.getId());
|
|
||||||
futures.addAll(postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, context.getGuild().getIdLong()));
|
|
||||||
|
|
||||||
return FutureUtils.toSingleFuture(futures);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -298,6 +308,10 @@ public class WarnServiceBean implements WarnService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessageToSend renderMessageModel(WarnContext warnContext) {
|
||||||
|
return templateService.renderEmbedTemplate(WARN_LOG_TEMPLATE, warnContext, warnContext.getGuild().getIdLong());
|
||||||
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
|
private CompletableFuture<Void> logDecayedWarnings(AServer server, List<Warning> warningsToDecay) {
|
||||||
log.debug("Loading members decaying {} warnings in server {}.", warningsToDecay.size(), server.getId());
|
log.debug("Loading members decaying {} warnings in server {}.", warningsToDecay.size(), server.getId());
|
||||||
HashMap<ServerSpecificId, FutureMemberPair> warningMembers = new HashMap<>();
|
HashMap<ServerSpecificId, FutureMemberPair> warningMembers = new HashMap<>();
|
||||||
|
|||||||
@@ -1,25 +1,44 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service.management;
|
package dev.sheldan.abstracto.moderation.service.management;
|
||||||
|
|
||||||
|
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.database.AUserInAServer;
|
||||||
|
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import dev.sheldan.abstracto.moderation.repository.InfractionRepository;
|
import dev.sheldan.abstracto.moderation.repository.InfractionRepository;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class InfractionManagementServiceBean implements InfractionManagementService{
|
public class InfractionManagementServiceBean implements InfractionManagementService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private InfractionRepository infractionRepository;
|
private InfractionRepository infractionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelManagementService channelManagementService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Infraction createInfraction(AUserInAServer aUserInAServer, Long points) {
|
public Infraction createInfraction(AUserInAServer target, Long points, String type, String description, AUserInAServer creator, Message message) {
|
||||||
|
AChannel channel;
|
||||||
|
if(message != null) {
|
||||||
|
channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
|
||||||
|
} else {
|
||||||
|
channel = null;
|
||||||
|
}
|
||||||
Infraction infraction = Infraction
|
Infraction infraction = Infraction
|
||||||
.builder()
|
.builder()
|
||||||
.user(aUserInAServer)
|
.user(target)
|
||||||
.server(aUserInAServer.getServerReference())
|
.infractionCreator(creator)
|
||||||
|
.server(target.getServerReference())
|
||||||
|
.decayed(false)
|
||||||
|
.logChannel(channel)
|
||||||
|
.logMessageId(message != null ? message.getIdLong() : null)
|
||||||
|
.type(type)
|
||||||
|
.description(description)
|
||||||
.points(points)
|
.points(points)
|
||||||
.build();
|
.build();
|
||||||
return infractionRepository.save(infraction);
|
return infractionRepository.save(infraction);
|
||||||
@@ -30,6 +49,16 @@ public class InfractionManagementServiceBean implements InfractionManagementServ
|
|||||||
return infractionRepository.findByUserAndDecayedFalse(aUserInAServer);
|
return infractionRepository.findByUserAndDecayedFalse(aUserInAServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Infraction> getInfractionsForUser(AUserInAServer aUserInAServer) {
|
||||||
|
return infractionRepository.findByUserOrderByCreated(aUserInAServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Infraction> getInfractionsForServer(AServer server) {
|
||||||
|
return infractionRepository.findByServerOrderByCreated(server);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Infraction loadInfraction(Long infraction) {
|
public Infraction loadInfraction(Long infraction) {
|
||||||
return infractionRepository.getOne(infraction);
|
return infractionRepository.getOne(infraction);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package dev.sheldan.abstracto.moderation.service.management;
|
||||||
|
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.InfractionParameter;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.embedded.InfractionParameterId;
|
||||||
|
import dev.sheldan.abstracto.moderation.repository.InfractionParameterRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class InfractionParameterManagementServiceBean implements InfractionParameterManagementService{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionParameterRepository infractionParameterRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfractionParameter createInfractionParameter(Infraction infraction, String key, String value) {
|
||||||
|
InfractionParameterId id = new InfractionParameterId(infraction.getId(), key);
|
||||||
|
InfractionParameter parameter = InfractionParameter
|
||||||
|
.builder()
|
||||||
|
.infractionParameterId(id)
|
||||||
|
.value(value)
|
||||||
|
.infraction(infraction)
|
||||||
|
.build();
|
||||||
|
return infractionParameterRepository.save(parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
|||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||||
|
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
||||||
|
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||||
import dev.sheldan.abstracto.moderation.repository.MuteRepository;
|
import dev.sheldan.abstracto.moderation.repository.MuteRepository;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -27,11 +29,20 @@ public class MuteManagementServiceBean implements MuteManagementService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserInServerManagementService userInServerManagementService;
|
private UserInServerManagementService userInServerManagementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InfractionManagementService infractionManagementService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mute createMute(AUserInAServer mutedUser, AUserInAServer mutingUser, String reason, Instant unMuteDate, AServerAChannelMessage muteMessage, String triggerKey, Long muteId) {
|
public Mute createMute(AUserInAServer mutedUser, AUserInAServer mutingUser, String reason, Instant unMuteDate, AServerAChannelMessage muteMessage, String triggerKey, Long muteId, Long infractionId) {
|
||||||
log.debug("Creating mute for user {} executed by user {} in server {}, user will be un-muted at {}",
|
log.debug("Creating mute for user {} executed by user {} in server {}, user will be un-muted at {}",
|
||||||
mutedUser.getUserReference().getId(), mutingUser.getUserReference().getId(), mutedUser.getServerReference().getId(), unMuteDate);
|
mutedUser.getUserReference().getId(), mutingUser.getUserReference().getId(), mutedUser.getServerReference().getId(), unMuteDate);
|
||||||
ServerSpecificId id = new ServerSpecificId(muteMessage.getServer().getId(), muteId);
|
Infraction infraction;
|
||||||
|
if(infractionId != null) {
|
||||||
|
infraction = infractionManagementService.loadInfraction(infractionId);
|
||||||
|
} else {
|
||||||
|
infraction = null;
|
||||||
|
}
|
||||||
|
ServerSpecificId id = new ServerSpecificId(mutedUser.getServerReference().getId(), muteId);
|
||||||
Mute mute = Mute
|
Mute mute = Mute
|
||||||
.builder()
|
.builder()
|
||||||
.mutedUser(mutedUser)
|
.mutedUser(mutedUser)
|
||||||
@@ -41,6 +52,7 @@ public class MuteManagementServiceBean implements MuteManagementService {
|
|||||||
.mutingChannel(muteMessage.getChannel())
|
.mutingChannel(muteMessage.getChannel())
|
||||||
.messageId(muteMessage.getMessageId())
|
.messageId(muteMessage.getMessageId())
|
||||||
.reason(reason)
|
.reason(reason)
|
||||||
|
.infraction(infraction)
|
||||||
.triggerKey(triggerKey)
|
.triggerKey(triggerKey)
|
||||||
.muteId(id)
|
.muteId(id)
|
||||||
.muteEnded(false)
|
.muteEnded(false)
|
||||||
@@ -76,6 +88,11 @@ public class MuteManagementServiceBean implements MuteManagementService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mute getAMuteOf(AUserInAServer userInAServer) {
|
public Mute getAMuteOf(AUserInAServer userInAServer) {
|
||||||
|
return getAMuteOfOptional(userInAServer).orElseThrow(NoMuteFoundException::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Mute> getAMuteOfOptional(AUserInAServer userInAServer) {
|
||||||
return muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer);
|
return muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +101,11 @@ public class MuteManagementServiceBean implements MuteManagementService {
|
|||||||
return getAMuteOf(userInServerManagementService.loadOrCreateUser(member));
|
return getAMuteOf(userInServerManagementService.loadOrCreateUser(member));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Mute> getAMuteOfOptional(Member member) {
|
||||||
|
return getAMuteOfOptional(userInServerManagementService.loadOrCreateUser(member));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Mute> getAllActiveMutesOf(AUserInAServer aUserInAServer) {
|
public List<Mute> getAllActiveMutesOf(AUserInAServer aUserInAServer) {
|
||||||
return muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(aUserInAServer);
|
return muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(aUserInAServer);
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service.management;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.MuteRole;
|
|
||||||
import dev.sheldan.abstracto.moderation.repository.MuteRoleRepository;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class MuteRoleManagementServiceBean implements MuteRoleManagementService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MuteRoleRepository muteRoleRepository;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MuteRole retrieveMuteRoleForServer(AServer server) {
|
|
||||||
return muteRoleRepository.findByRoleServer(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MuteRole createMuteRoleForServer(AServer server, ARole role) {
|
|
||||||
log.debug("Creating mute role for server {} to be role {}", server.getId(), role.getId());
|
|
||||||
MuteRole muteRole = MuteRole
|
|
||||||
.builder()
|
|
||||||
.role(role)
|
|
||||||
.roleServer(server)
|
|
||||||
.build();
|
|
||||||
return muteRoleRepository.save(muteRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MuteRole> retrieveMuteRolesForServer(AServer server) {
|
|
||||||
return muteRoleRepository.findAllByRoleServer(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MuteRole setMuteRoleForServer(AServer server, ARole role) {
|
|
||||||
log.info("Setting muted role for server {} to role {}", server.getId(), role.getId());
|
|
||||||
if(!muteRoleForServerExists(server)) {
|
|
||||||
log.debug("Mute role did not exist yet, updating for server {}.", server.getId());
|
|
||||||
return createMuteRoleForServer(server, role);
|
|
||||||
} else {
|
|
||||||
MuteRole existing = retrieveMuteRoleForServer(server);
|
|
||||||
log.debug("Updating mute role for server {} to be role {} instead.", server.getId(), role.getId());
|
|
||||||
existing.setRole(role);
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean muteRoleForServerExists(AServer server) {
|
|
||||||
return muteRoleRepository.existsByRoleServer(server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -30,7 +31,8 @@ public class ReactionReportManagementServiceBean implements ReactionReportManage
|
|||||||
@Override
|
@Override
|
||||||
public Optional<ReactionReport> findRecentReactionReportAboutUser(AUserInAServer aUserInAServer, Duration maxAge) {
|
public Optional<ReactionReport> findRecentReactionReportAboutUser(AUserInAServer aUserInAServer, Duration maxAge) {
|
||||||
Instant maxCreation = Instant.now().minus(maxAge);
|
Instant maxCreation = Instant.now().minus(maxAge);
|
||||||
return repository.findByReportedUserAndCreatedLessThan(aUserInAServer, maxCreation);
|
List<ReactionReport> foundReports = repository.findByReportedUserAndCreatedLessThan(aUserInAServer, maxCreation);
|
||||||
|
return foundReports.isEmpty() ? Optional.empty() : Optional.of(foundReports.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -104,5 +104,10 @@ public class WarnManagementServiceBean implements WarnManagementService {
|
|||||||
warnRepository.delete(warning);
|
warnRepository.delete(warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Warning> findWarnByInfraction(Long infractionId) {
|
||||||
|
return warnRepository.findByInfraction_Id(infractionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<property name="moderationModule" value="(SELECT id FROM module WHERE name = 'moderation')"/>
|
||||||
|
<property name="infractionsFeature" value="(SELECT id FROM feature WHERE key = 'infractions')"/>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="moderation_infraction-commands">
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="infractions"/>
|
||||||
|
<column name="module_id" valueComputed="${moderationModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${infractionsFeature}"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="command">
|
||||||
|
<column name="name" value="editInfraction"/>
|
||||||
|
<column name="module_id" valueComputed="${moderationModule}"/>
|
||||||
|
<column name="feature_id" valueComputed="${infractionsFeature}"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="moderation_setMuteRole-cleanup">
|
||||||
|
<delete tableName="command_in_server_allowed_role">
|
||||||
|
<where>command_in_server_id in (select cs.command_in_server_id from command_in_server cs inner join command c on c.id = cs.command_id and c.name = 'setMuteRole') </where>
|
||||||
|
</delete>
|
||||||
|
<delete tableName="command_in_server_alias">
|
||||||
|
<where>command_in_server_id in (select cs.command_in_server_id from command_in_server cs inner join command c on c.id = cs.command_id and c.name = 'setMuteRole') </where>
|
||||||
|
</delete>
|
||||||
|
<delete tableName="command_in_server">
|
||||||
|
<where>command_id=(select id from command where name = 'setMuteRole')</where>
|
||||||
|
</delete>
|
||||||
|
<delete tableName="command">
|
||||||
|
<where>name='setMuteRole'</where>
|
||||||
|
</delete>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<property name="moderationFeature" value="(SELECT id FROM feature WHERE key = 'moderation')"/>
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="moderation_context_command">
|
||||||
|
<insert tableName="context_command">
|
||||||
|
<column name="name" value="report_message"/>
|
||||||
|
<column name="type" value="MESSAGE"/>
|
||||||
|
<column name="feature_id" valueComputed="${moderationFeature}"/>
|
||||||
|
</insert>
|
||||||
|
<insert tableName="context_command">
|
||||||
|
<column name="name" value="report_message_context"/>
|
||||||
|
<column name="type" value="MESSAGE"/>
|
||||||
|
<column name="feature_id" valueComputed="${moderationFeature}"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<include file="context_command.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="feature_mode.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
|
||||||
|
<changeSet author="Sheldan" id="delete_manual_unmuting_log_feature_mode">
|
||||||
|
<delete tableName="feature_mode">
|
||||||
|
<where>feature_mode='manualUnMuteLogging'</where>
|
||||||
|
</delete>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<changeSet author="Sheldan" id="infraction-type-description">
|
||||||
|
<addColumn tableName="infraction">
|
||||||
|
<column name="type" type="VARCHAR(32)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="description" type="VARCHAR(2048)">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="log_message_id" type="BIGINT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="log_channel_id" type="BIGINT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="infraction_creator_user_in_server_id" type="BIGINT">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
<addNotNullConstraint columnName="decayed"
|
||||||
|
tableName="infraction"
|
||||||
|
validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="infraction_creator_user_in_server_id" baseTableName="infraction" constraintName="fk_infraction_creator_user"
|
||||||
|
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||||
|
referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="log_channel_id" baseTableName="infraction" constraintName="fk_infraction_log_channel"
|
||||||
|
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||||
|
referencedColumnNames="id" referencedTableName="channel" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<changeSet author="Sheldan" id="infraction_parameter-table">
|
||||||
|
<createTable tableName="infraction_parameter">
|
||||||
|
<column name="key" type="VARCHAR(255)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="value" type="VARCHAR(255)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="infraction_id" type="BIGINT">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||||
|
</createTable>
|
||||||
|
<addPrimaryKey columnNames="infraction_id, key" tableName="infraction_parameter" constraintName="pk_infraction_parameter" validate="true"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="infraction_id" baseTableName="infraction_parameter" constraintName="fk_infraction_parameter_infraction"
|
||||||
|
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||||
|
referencedColumnNames="id" referencedTableName="infraction" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<changeSet author="Sheldan" id="mute-infraction_id">
|
||||||
|
<addColumn tableName="mute">
|
||||||
|
<column name="infraction_id" type="BIGINT" />
|
||||||
|
</addColumn>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="infraction_id" baseTableName="mute" constraintName="fk_mute_infraction"
|
||||||
|
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||||
|
referencedColumnNames="id" referencedTableName="infraction" validate="true"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||||
|
<include file="infraction.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="infraction_parameter.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="mute.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -13,4 +13,5 @@
|
|||||||
<include file="1.3.4/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.3.4/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.3.9/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.3.9/collection.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="1.3.10/collection.xml" relativeToChangelogFile="true"/>
|
<include file="1.3.10/collection.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -49,6 +49,14 @@ abstracto.featureModes.infractionReporting.featureName=infractions
|
|||||||
abstracto.featureModes.infractionReporting.mode=infractionReporting
|
abstracto.featureModes.infractionReporting.mode=infractionReporting
|
||||||
abstracto.featureModes.infractionReporting.enabled=true
|
abstracto.featureModes.infractionReporting.enabled=true
|
||||||
|
|
||||||
|
abstracto.featureModes.anonymousReportReactions.featureName=reportReactions
|
||||||
|
abstracto.featureModes.anonymousReportReactions.mode=anonymousReportReactions
|
||||||
|
abstracto.featureModes.anonymousReportReactions.enabled=false
|
||||||
|
|
||||||
|
abstracto.featureModes.singularReportReactions.featureName=reportReactions
|
||||||
|
abstracto.featureModes.singularReportReactions.mode=singularReportReactions
|
||||||
|
abstracto.featureModes.singularReportReactions.enabled=false
|
||||||
|
|
||||||
abstracto.systemConfigs.infractionLvl1.name=infractionLvl1
|
abstracto.systemConfigs.infractionLvl1.name=infractionLvl1
|
||||||
abstracto.systemConfigs.infractionLvl1.longValue=10
|
abstracto.systemConfigs.infractionLvl1.longValue=10
|
||||||
|
|
||||||
@@ -68,7 +76,16 @@ abstracto.systemConfigs.infractionLevels.name=infractionLevels
|
|||||||
abstracto.systemConfigs.infractionLevels.longValue=5
|
abstracto.systemConfigs.infractionLevels.longValue=5
|
||||||
|
|
||||||
abstracto.systemConfigs.warnInfractionPoints.name=warnInfractionPoints
|
abstracto.systemConfigs.warnInfractionPoints.name=warnInfractionPoints
|
||||||
abstracto.systemConfigs.warnInfractionPoints.longValue=0
|
abstracto.systemConfigs.warnInfractionPoints.longValue=50
|
||||||
|
|
||||||
|
abstracto.systemConfigs.banInfractionPoints.name=banInfractionPoints
|
||||||
|
abstracto.systemConfigs.banInfractionPoints.longValue=150
|
||||||
|
|
||||||
|
abstracto.systemConfigs.kickInfractionPoints.name=kickInfractionPoints
|
||||||
|
abstracto.systemConfigs.kickInfractionPoints.longValue=20
|
||||||
|
|
||||||
|
abstracto.systemConfigs.muteInfractionPoints.name=muteInfractionPoints
|
||||||
|
abstracto.systemConfigs.muteInfractionPoints.longValue=10
|
||||||
|
|
||||||
abstracto.featureModes.automaticWarnDecayLogging.featureName=warnDecay
|
abstracto.featureModes.automaticWarnDecayLogging.featureName=warnDecay
|
||||||
abstracto.featureModes.automaticWarnDecayLogging.mode=automaticWarnDecayLogging
|
abstracto.featureModes.automaticWarnDecayLogging.mode=automaticWarnDecayLogging
|
||||||
@@ -78,6 +95,3 @@ abstracto.featureModes.notifyMemberWarningDecays.featureName=warnDecay
|
|||||||
abstracto.featureModes.notifyMemberWarningDecays.mode=notifyMemberWarningDecays
|
abstracto.featureModes.notifyMemberWarningDecays.mode=notifyMemberWarningDecays
|
||||||
abstracto.featureModes.notifyMemberWarningDecays.enabled=true
|
abstracto.featureModes.notifyMemberWarningDecays.enabled=true
|
||||||
|
|
||||||
abstracto.featureModes.manualUnMuteLogging.featureName=muting
|
|
||||||
abstracto.featureModes.manualUnMuteLogging.mode=manualUnMuteLogging
|
|
||||||
abstracto.featureModes.manualUnMuteLogging.enabled=true
|
|
||||||
|
|||||||
@@ -1,60 +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.models.database.ARole;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
|
||||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
|
||||||
import dev.sheldan.abstracto.moderation.command.SetMuteRole;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
|
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class SetMuteRoleTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private SetMuteRole testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteRoleManagementService muteRoleManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private RoleManagementService roleManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServerManagementService serverManagementService;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteCommand() {
|
|
||||||
Role role = Mockito.mock(Role.class);
|
|
||||||
Long roleId = 5L;
|
|
||||||
when(role.getIdLong()).thenReturn(roleId);
|
|
||||||
ARole aRole = Mockito.mock(ARole.class);
|
|
||||||
when(roleManagementService.findRole(roleId)).thenReturn(aRole);
|
|
||||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(role));
|
|
||||||
when(role.getGuild()).thenReturn(parameters.getGuild());
|
|
||||||
AServer server = Mockito.mock(AServer.class);
|
|
||||||
when(serverManagementService.loadServer(parameters.getGuild())).thenReturn(server);
|
|
||||||
CommandResult result = testUnit.execute(parameters);
|
|
||||||
verify(muteRoleManagementService, times(1)).setMuteRoleForServer(server, aRole);
|
|
||||||
CommandTestUtilities.checkSuccessfulCompletion(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void validateCommand() {
|
|
||||||
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +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.models.database.AUserInAServer;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
|
||||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
|
||||||
import dev.sheldan.abstracto.moderation.command.UnMute;
|
|
||||||
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.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 UnMuteTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private UnMute testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteService muteService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteManagementService muteManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member memberToUnMute;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnMuteCommand() {
|
|
||||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToUnMute));
|
|
||||||
when(memberToUnMute.getGuild()).thenReturn(parameters.getGuild());
|
|
||||||
AUserInAServer user = Mockito.mock(AUserInAServer.class);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberToUnMute)).thenReturn(user);
|
|
||||||
when(muteService.unMuteUser(user)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
|
||||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = NoMuteFoundException.class)
|
|
||||||
public void testUnMuteCommandWithoutExistingMute() {
|
|
||||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(memberToUnMute));
|
|
||||||
when(memberToUnMute.getGuild()).thenReturn(parameters.getGuild());
|
|
||||||
AUserInAServer user = Mockito.mock(AUserInAServer.class);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberToUnMute)).thenReturn(user);
|
|
||||||
when(muteService.unMuteUser(user)).thenThrow(new NoMuteFoundException());
|
|
||||||
testUnit.executeAsync(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void validateCommand() {
|
|
||||||
CommandConfigValidator.validateCommandConfiguration(testUnit.getConfiguration());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.listener;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.MemberJoinModel;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class JoinMuteListenerTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private JoinMuteListener testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteManagementService muteManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteService muteService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer joiningUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServerUser serverUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MemberJoinModel model;
|
|
||||||
|
|
||||||
private static final Long SERVER_ID = 3L;
|
|
||||||
private static final Long USER_ID = 4L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNonMutedUserJoins() {
|
|
||||||
when(serverUser.getUserId()).thenReturn(USER_ID);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(SERVER_ID, USER_ID)).thenReturn(joiningUser);
|
|
||||||
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(false);
|
|
||||||
when(model.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(model.getJoiningUser()).thenReturn(serverUser);
|
|
||||||
testUnit.execute(model);
|
|
||||||
verify(muteService, times(0)).applyMuteRole(joiningUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMutedUserJoins() {
|
|
||||||
when(model.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(serverUser.getUserId()).thenReturn(USER_ID);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(SERVER_ID, USER_ID)).thenReturn(joiningUser);
|
|
||||||
when(muteManagementService.hasActiveMute(joiningUser)).thenReturn(true);
|
|
||||||
when(model.getJoiningUser()).thenReturn(serverUser);
|
|
||||||
testUnit.execute(model);
|
|
||||||
verify(muteService, times(1)).applyMuteRole(joiningUser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
|
||||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.ModerationPostTarget;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.KickLogModel;
|
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
|
||||||
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class KickServiceBeanTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private KickServiceBean testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private TemplateService templateService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PostTargetService postTargetService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private FeatureModeService featureModeService;
|
|
||||||
|
|
||||||
private static final Long SERVER_ID = 1L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testKickMemberWithLog() {
|
|
||||||
User user = Mockito.mock(User.class);
|
|
||||||
Member member = Mockito.mock(Member.class);
|
|
||||||
when(member.getUser()).thenReturn(user);
|
|
||||||
when(user.getIdLong()).thenReturn(6L);
|
|
||||||
Guild mockedGuild = Mockito.mock(Guild.class);
|
|
||||||
when(mockedGuild.getIdLong()).thenReturn(SERVER_ID);
|
|
||||||
when(member.getGuild()).thenReturn(mockedGuild);
|
|
||||||
String reason = "reason";
|
|
||||||
AuditableRestAction<Void> mockedAction = Mockito.mock(AuditableRestAction.class);
|
|
||||||
when(mockedGuild.kick(member, reason)).thenReturn(mockedAction);
|
|
||||||
when(mockedAction.submit()).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
KickLogModel model = Mockito.mock(KickLogModel.class);
|
|
||||||
when(model.getGuild()).thenReturn(mockedGuild);
|
|
||||||
testUnit.kickMember(member, reason, model);
|
|
||||||
verify(postTargetService, times(0)).sendEmbedInPostTarget(any(MessageToSend.class), eq(ModerationPostTarget.KICK_LOG), eq(SERVER_ID));
|
|
||||||
verify(templateService, times(1)).renderEmbedTemplate(KickServiceBean.KICK_LOG_TEMPLATE, model, SERVER_ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,458 +0,0 @@
|
|||||||
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.ServerSpecificId;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.*;
|
|
||||||
import dev.sheldan.abstracto.core.service.*;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
|
||||||
import dev.sheldan.abstracto.moderation.exception.MuteRoleNotSetupException;
|
|
||||||
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.MuteRole;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteContext;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteNotification;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.MuteRoleManagementService;
|
|
||||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
|
|
||||||
import static dev.sheldan.abstracto.moderation.service.MuteServiceBean.MUTE_NOTIFICATION_TEMPLATE;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class MuteServiceBeanTest {
|
|
||||||
@InjectMocks
|
|
||||||
private MuteServiceBean testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteRoleManagementService muteRoleManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private RoleService roleService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private SchedulerService schedulerService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteManagementService muteManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private TemplateService templateService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private GuildService guildService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MemberService memberService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MessageService messageService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PostTargetService postTargetService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteServiceBean self;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ScheduledExecutorService executorService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ChannelManagementService channelManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer userBeingMuted;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer userMuting;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private User jdaUserBeingMuted;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member memberBeingMuted;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member memberMuting;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AServer server;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AChannel aChannel;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MessageChannel channel;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServerChannelMessage cause;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Guild guild;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ARole aRole;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteRole muteRole;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MessageToSend messageToSend;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUser user;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Mute mute;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServerManagementService serverManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private CounterService counterService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private FeatureModeService featureModeService;
|
|
||||||
|
|
||||||
private static final Long CHANNEL_ID = 8L;
|
|
||||||
private static final String REASON = "reason";
|
|
||||||
private static final String NOTIFICATION_TEXT = "text";
|
|
||||||
private static final String TRIGGER = "trigger";
|
|
||||||
public static final Long MUTE_ID = 6L;
|
|
||||||
public static final Long SERVER_ID = 7L;
|
|
||||||
public static final Long USER_MUTING_ID = 4L;
|
|
||||||
public static final Long USER_BEING_MUTED_ID = 3L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMuteUserWithScheduler() {
|
|
||||||
Instant unMuteDate = longerMute();
|
|
||||||
when(cause.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
FullUserInServer mutedUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
FullUserInServer mutingUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
setupFullUsers(mutedUser, mutingUser);
|
|
||||||
when(muteRole.getRole()).thenReturn(aRole);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class), eq(SERVER_ID))).thenReturn(NOTIFICATION_TEXT);
|
|
||||||
|
|
||||||
when(messageService.sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(roleService.addRoleToUserAsync(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
|
|
||||||
CompletableFuture<Void> future = testUnit.muteUserInServer(mutedUser, mutingUser, REASON, unMuteDate, cause);
|
|
||||||
future.join();
|
|
||||||
Assert.assertFalse(future.isCompletedExceptionally());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupFullUsers(FullUserInServer mutedUser, FullUserInServer mutingUser) {
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(mutedUser.getAUserInAServer()).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(mutedUser.getMember()).thenReturn(memberBeingMuted);
|
|
||||||
when(mutingUser.getMember()).thenReturn(memberMuting);
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMuteWithDirectUnMute() {
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
FullUserInServer mutedUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
FullUserInServer mutingUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
setupFullUsers(mutedUser, mutingUser);
|
|
||||||
Instant unMuteDate = shorterMute();
|
|
||||||
when(cause.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
when(muteRole.getRole()).thenReturn(aRole);
|
|
||||||
String notificationText = "text";
|
|
||||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class), eq(SERVER_ID))).thenReturn(notificationText);
|
|
||||||
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(roleService.addRoleToUserAsync(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
CompletableFuture<Void> future = testUnit.muteUserInServer(mutedUser, mutingUser, REASON, unMuteDate, cause);
|
|
||||||
future.join();
|
|
||||||
Assert.assertFalse(future.isCompletedExceptionally() );
|
|
||||||
verifyDirectMute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = MuteRoleNotSetupException.class)
|
|
||||||
public void testMuteUserWithoutMuteRole() {
|
|
||||||
FullUserInServer mutedUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
when(mutedUser.getAUserInAServer()).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(false);
|
|
||||||
FullUserInServer mutingUser = Mockito.mock(FullUserInServer.class);
|
|
||||||
ServerChannelMessage serverChannelMessage = mock(ServerChannelMessage.class);
|
|
||||||
testUnit.muteUserInServer(mutedUser, mutingUser, REASON, longerMute(), serverChannelMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCancelUnMuteJob() {
|
|
||||||
when(mute.getTriggerKey()).thenReturn(TRIGGER);
|
|
||||||
testUnit.cancelUnMuteJob(mute);
|
|
||||||
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCancelNotExistingJob() {
|
|
||||||
testUnit.cancelUnMuteJob(mute);
|
|
||||||
verify(schedulerService, times(0)).stopTrigger(anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMuteMember() {
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberBeingMuted)).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberMuting)).thenReturn(userMuting);
|
|
||||||
Instant unMuteDate = shorterMute();
|
|
||||||
when(cause.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
|
|
||||||
String notificationText = "text";
|
|
||||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class), eq(SERVER_ID))).thenReturn(notificationText);
|
|
||||||
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(roleService.addRoleToUserAsync(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
testUnit.muteMember(memberBeingMuted, memberMuting, REASON, unMuteDate, cause);
|
|
||||||
verifyDirectMute();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMuteMemberWithLog() {
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberBeingMuted)).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberMuting)).thenReturn(userMuting);
|
|
||||||
Instant unMuteDate = shorterMute();
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
|
|
||||||
ServerChannelMessage serverChannelMessage = Mockito.mock(ServerChannelMessage.class);
|
|
||||||
when(serverChannelMessage.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
MuteContext muteLog = Mockito.mock(MuteContext.class);
|
|
||||||
when(muteLog.getMutedUser()).thenReturn(memberBeingMuted);
|
|
||||||
when(muteLog.getMutingUser()).thenReturn(memberMuting);
|
|
||||||
when(muteLog.getContext()).thenReturn(serverChannelMessage);
|
|
||||||
when(muteLog.getMuteTargetDate()).thenReturn(unMuteDate);
|
|
||||||
when(server.getId()).thenReturn(SERVER_ID);
|
|
||||||
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
|
|
||||||
String notificationText = "text";
|
|
||||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class), eq(SERVER_ID))).thenReturn(notificationText);
|
|
||||||
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(templateService.renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteContext.class), eq(SERVER_ID))).thenReturn(messageToSend);
|
|
||||||
when(roleService.addRoleToUserAsync(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
testUnit.muteMemberWithLog(muteLog);
|
|
||||||
verifyDirectMute();
|
|
||||||
verify(templateService, times(1)).renderEmbedTemplate(eq(MuteServiceBean.MUTE_LOG_TEMPLATE), any(MuteContext.class), eq(SERVER_ID));
|
|
||||||
verify(postTargetService, times(1)).sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, SERVER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMuteMemberWithoutLog() {
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberBeingMuted)).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberMuting)).thenReturn(userMuting);
|
|
||||||
Instant unMuteDate = shorterMute();
|
|
||||||
when(memberBeingMuted.getGuild()).thenReturn(guild);
|
|
||||||
when(memberBeingMuted.getUser()).thenReturn(jdaUserBeingMuted);
|
|
||||||
when(muteRoleManagementService.muteRoleForServerExists(server)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
|
|
||||||
ServerChannelMessage serverChannelMessage = Mockito.mock(ServerChannelMessage.class);
|
|
||||||
when(serverChannelMessage.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
MuteContext muteLog = Mockito.mock(MuteContext.class);
|
|
||||||
when(muteLog.getMutedUser()).thenReturn(memberBeingMuted);
|
|
||||||
when(muteLog.getMutingUser()).thenReturn(memberMuting);
|
|
||||||
when(muteLog.getContext()).thenReturn(serverChannelMessage);
|
|
||||||
when(muteLog.getMuteTargetDate()).thenReturn(unMuteDate);
|
|
||||||
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
|
|
||||||
String notificationText = "text";
|
|
||||||
when(templateService.renderTemplate(eq(MUTE_NOTIFICATION_TEMPLATE), any(MuteNotification.class), eq(SERVER_ID))).thenReturn(notificationText);
|
|
||||||
when(messageService.sendMessageToUser(memberBeingMuted.getUser(), notificationText)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(roleService.addRoleToUserAsync(userBeingMuted, muteRole.getRole())).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
testUnit.muteMemberWithLog(muteLog);
|
|
||||||
verifyDirectMute();
|
|
||||||
verify(postTargetService, times(0)).sendEmbedInPostTarget(messageToSend, MutingPostTarget.MUTE_LOG, SERVER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnMuteMemberWhoseMuteEnded() {
|
|
||||||
when(mute.getMuteEnded()).thenReturn(true);
|
|
||||||
when(mute.getMutedUser()).thenReturn(userBeingMuted);
|
|
||||||
when(muteManagementService.hasActiveMute(userBeingMuted)).thenReturn(true);
|
|
||||||
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
|
|
||||||
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
|
|
||||||
when(guildService.getGuildById(SERVER_ID)).thenReturn(guild);
|
|
||||||
testUnit.unMuteUser(userBeingMuted);
|
|
||||||
verifyNoUnMuteHappened();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEndMute() {
|
|
||||||
setupUnMuteMocks();
|
|
||||||
when(mute.getMutedUser()).thenReturn(userBeingMuted);
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(mute.getMutingUser()).thenReturn(userMuting);
|
|
||||||
when(mute.getServer()).thenReturn(server);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
when(muteRole.getRole()).thenReturn(aRole);
|
|
||||||
when(muteManagementService.findMuteOptional(MUTE_ID, SERVER_ID)).thenReturn(Optional.of(mute));
|
|
||||||
when(roleService.removeRoleFromUserAsync(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(memberService.getMemberInServerAsync(userBeingMuted)).thenReturn(CompletableFuture.completedFuture(memberBeingMuted));
|
|
||||||
when(memberService.getMemberInServerAsync(userMuting)).thenReturn(CompletableFuture.completedFuture(memberMuting));
|
|
||||||
testUnit.endMute(MUTE_ID, SERVER_ID);
|
|
||||||
verify(self, times(1)).sendUnmuteLog(eq(MUTE_ID), any(Guild.class), any(CompletableFuture.class), any(CompletableFuture.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendUnmuteLog() {
|
|
||||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
|
||||||
when(muteManagementService.findMute(MUTE_ID, SERVER_ID)).thenReturn(mute);
|
|
||||||
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
|
|
||||||
when(serverManagementService.loadServer(SERVER_ID)).thenReturn(server);
|
|
||||||
testUnit.sendUnmuteLog(MUTE_ID, guild, CompletableFuture.completedFuture(memberMuting), CompletableFuture.completedFuture(memberBeingMuted));
|
|
||||||
verify(self, times(1)).endMuteInDatabase(MUTE_ID, SERVER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = NoMuteFoundException.class)
|
|
||||||
public void testEndNonExistingMute() {
|
|
||||||
when(muteManagementService.findMuteOptional(MUTE_ID, SERVER_ID)).thenReturn(Optional.empty());
|
|
||||||
testUnit.endMute(MUTE_ID, SERVER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnMuteMemberInGuild() {
|
|
||||||
executeUnMuteWithLogTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCompletelyUnMuteNotMutedUser() {
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(muteManagementService.getAllActiveMutesOf(userBeingMuted)).thenReturn(Arrays.asList());
|
|
||||||
testUnit.completelyUnMuteUser(userBeingMuted);
|
|
||||||
verify(muteManagementService, times(0)).saveMute(any(Mute.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCompletelyUnMuteNotScheduledMuteUser() {
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(muteManagementService.getAllActiveMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
|
|
||||||
testUnit.completelyUnMuteUser(userBeingMuted);
|
|
||||||
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
|
|
||||||
verify(schedulerService, times(0)).stopTrigger(anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCompletelyUnMuteScheduledMuteUser() {
|
|
||||||
when(mute.getTriggerKey()).thenReturn(TRIGGER);
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(muteManagementService.getAllActiveMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
|
|
||||||
testUnit.completelyUnMuteUser(userBeingMuted);
|
|
||||||
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
|
|
||||||
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCompletelyUnMuteMember() {
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(userBeingMuted.getServerReference()).thenReturn(server);
|
|
||||||
when(mute.getTriggerKey()).thenReturn(TRIGGER);
|
|
||||||
when(muteManagementService.getAllActiveMutesOf(userBeingMuted)).thenReturn(Arrays.asList(mute));
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(memberBeingMuted)).thenReturn(userBeingMuted);
|
|
||||||
testUnit.completelyUnMuteMember(memberBeingMuted);
|
|
||||||
verify(muteManagementService, times(1)).saveMute(any(Mute.class));
|
|
||||||
verify(schedulerService, times(1)).stopTrigger(TRIGGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void verifyScheduling() {
|
|
||||||
Instant unMuteDate = shorterMute();
|
|
||||||
MuteContext muteLog = Mockito.mock(MuteContext.class);
|
|
||||||
when(muteLog.getMuteTargetDate()).thenReturn(unMuteDate);
|
|
||||||
when(muteLog.getMuteId()).thenReturn(MUTE_ID);
|
|
||||||
ServerChannelMessage serverContext = Mockito.mock(ServerChannelMessage.class);
|
|
||||||
when(serverContext.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(serverContext.getChannelId()).thenReturn(CHANNEL_ID);
|
|
||||||
when(channelManagementService.loadChannel(CHANNEL_ID)).thenReturn(aChannel);
|
|
||||||
when(muteLog.getContext()).thenReturn(serverContext);
|
|
||||||
testUnit.persistMute(muteLog);
|
|
||||||
verify(executorService, times(1)).schedule(any(Runnable.class), anyLong(), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyNoUnMuteHappened() {
|
|
||||||
verify(muteManagementService, times(0)).saveMute(any(Mute.class));
|
|
||||||
verify(roleService, times(0)).removeRoleFromUser(eq(userBeingMuted), any(ARole.class));
|
|
||||||
verify(postTargetService, times(0)).sendEmbedInPostTarget(any(MessageToSend.class), eq(MutingPostTarget.MUTE_LOG), eq(SERVER_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeUnMuteWithLogTest() {
|
|
||||||
when(userBeingMuted.getUserReference()).thenReturn(user);
|
|
||||||
when(mute.getMutedUser()).thenReturn(userBeingMuted);
|
|
||||||
when(mute.getMutingUser()).thenReturn(userMuting);
|
|
||||||
when(mute.getServer()).thenReturn(server);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
when(muteRole.getRole()).thenReturn(aRole);
|
|
||||||
setupUnMuteMocks();
|
|
||||||
when(roleService.removeRoleFromUserAsync(userBeingMuted, aRole)).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(memberService.getMemberInServerAsync(userBeingMuted)).thenReturn(CompletableFuture.completedFuture(memberBeingMuted));
|
|
||||||
when(memberService.getMemberInServerAsync(userMuting)).thenReturn(CompletableFuture.completedFuture(memberMuting));
|
|
||||||
testUnit.unMuteUser(userBeingMuted);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupUnMuteMocks() {
|
|
||||||
when(mute.getMuteId()).thenReturn(new ServerSpecificId(SERVER_ID, MUTE_ID));
|
|
||||||
when(muteManagementService.getAMuteOf(userBeingMuted)).thenReturn(mute);
|
|
||||||
when(muteManagementService.hasActiveMute(userBeingMuted)).thenReturn(true);
|
|
||||||
when(muteRoleManagementService.retrieveMuteRoleForServer(server)).thenReturn(muteRole);
|
|
||||||
when(guildService.getGuildById(server.getId())).thenReturn(guild);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyDirectMute() {
|
|
||||||
verify(messageService, times(1)).sendMessageToUser(jdaUserBeingMuted, NOTIFICATION_TEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Instant longerMute() {
|
|
||||||
return Instant.now().plus(Duration.ofHours(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Instant shorterMute() {
|
|
||||||
return Instant.now().plus(Duration.ofSeconds(4));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
|
||||||
import dev.sheldan.abstracto.core.models.property.SystemConfigProperty;
|
|
||||||
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.test.command.CommandTestUtilities;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.WarningDecayFeatureConfig;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.mode.WarnDecayMode;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.mode.WarningMode;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.WarningPostTarget;
|
|
||||||
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.WarnNotification;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.template.job.WarnDecayLogModel;
|
|
||||||
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
|
|
||||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
|
||||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.User;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.*;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import static dev.sheldan.abstracto.moderation.service.WarnServiceBean.WARNINGS_COUNTER_KEY;
|
|
||||||
import static dev.sheldan.abstracto.moderation.service.WarnServiceBean.WARN_LOG_TEMPLATE;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class WarnServiceBeanTest {
|
|
||||||
|
|
||||||
public static final long WARN_ID = 8L;
|
|
||||||
@InjectMocks
|
|
||||||
private WarnServiceBean testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private WarnManagementService warnManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PostTargetService postTargetService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private TemplateService templateService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MemberService memberService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ConfigService configService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private WarnServiceBean self;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member warnedMember;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member warningMember;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Member secondWarnedMember;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Guild guild;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MessageToSend messageToSend;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private User warnedSimpleUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private WarnContext context;
|
|
||||||
|
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<WarnDecayLogModel> warnDecayLogModelArgumentCaptor;
|
|
||||||
|
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<WarnNotification> notificationCaptor;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AServer server;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer warningUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer firstWarnedUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUserInAServer secondWarnedUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUser firstAUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUser secondAUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AUser thirdAUser;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Warning firstWarning;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Warning secondWarning;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ServerManagementService serverManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private CounterService counterService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MessageService messageService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private FeatureModeService featureModeService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private DefaultConfigManagementService defaultConfigManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private FeatureFlagService featureFlagService;
|
|
||||||
|
|
||||||
private static final String NOTIFICATION_TEXT = "text";
|
|
||||||
private static final String GUILD_NAME = "guild";
|
|
||||||
private static final Long SERVER_ID = 4L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayWarning() {
|
|
||||||
Instant date = Instant.now();
|
|
||||||
when(firstWarning.getWarnId()).thenReturn(new ServerSpecificId(SERVER_ID, 4L));
|
|
||||||
testUnit.decayWarning(firstWarning, date);
|
|
||||||
verify(firstWarning, times(1)).setDecayed(true);
|
|
||||||
verify(firstWarning, times(1)).setDecayDate(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayWarningsForServer() {
|
|
||||||
setupWarnDecay();
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.AUTOMATIC_WARN_DECAY, server, WarnDecayMode.AUTOMATIC_WARN_DECAY_LOG)).thenReturn(true);
|
|
||||||
testUnit.decayWarningsForServer(server);
|
|
||||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayWarningsForServerWithoutLog() {
|
|
||||||
setupWarnDecay();
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.AUTOMATIC_WARN_DECAY, server, WarnDecayMode.AUTOMATIC_WARN_DECAY_LOG)).thenReturn(false);
|
|
||||||
testUnit.decayWarningsForServer(server);
|
|
||||||
verify(self, times(0)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayAllWarningsForServer() {
|
|
||||||
setupWarnDecay();
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.WARNING, server, WarningMode.WARN_DECAY_LOG)).thenReturn(true);
|
|
||||||
testUnit.decayAllWarningsForServer(server);
|
|
||||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayAllWarningsForServerWithoutLog() {
|
|
||||||
setupWarnDecay();
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.WARNING, server, WarningMode.WARN_DECAY_LOG)).thenReturn(false);
|
|
||||||
testUnit.decayAllWarningsForServer(server);
|
|
||||||
verify(self, times(0)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayAllWarningsWithoutWarningsWithoutLog() {
|
|
||||||
List<Warning> warnings = Collections.emptyList();
|
|
||||||
when(server.getId()).thenReturn(SERVER_ID);
|
|
||||||
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.WARNING, server, WarningMode.WARN_DECAY_LOG)).thenReturn(false);
|
|
||||||
testUnit.decayAllWarningsForServer(server);
|
|
||||||
verify(self, times(0)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecayAllWarningsWithoutWarningsWithLog() {
|
|
||||||
List<Warning> warnings = Collections.emptyList();
|
|
||||||
when(server.getId()).thenReturn(SERVER_ID);
|
|
||||||
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
|
|
||||||
when(featureModeService.featureModeActive(ModerationFeatureDefinition.WARNING, server, WarningMode.WARN_DECAY_LOG)).thenReturn(true);
|
|
||||||
testUnit.decayAllWarningsForServer(server);
|
|
||||||
verify(self, times(1)).renderAndSendWarnDecayLogs(eq(SERVER_ID), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWarnFullUser() {
|
|
||||||
setupWarnContext();
|
|
||||||
setupMocksForWarning();
|
|
||||||
when(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, SERVER_ID)).thenReturn(false);
|
|
||||||
CompletableFuture<Void> future = testUnit.notifyAndLogFullUserWarning(context);
|
|
||||||
future.join();
|
|
||||||
Assert.assertFalse(future.isCompletedExceptionally());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupWarnContext() {
|
|
||||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
|
||||||
when(context.getGuild()).thenReturn(guild);
|
|
||||||
when(context.getWarnedMember()).thenReturn(warnedMember);
|
|
||||||
when(context.getMember()).thenReturn(warningMember);
|
|
||||||
when(counterService.getNextCounterValue(server, WARNINGS_COUNTER_KEY)).thenReturn(WARN_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setupMocksForWarning() {
|
|
||||||
setupWarnings();
|
|
||||||
when(warnedMember.getGuild()).thenReturn(guild);
|
|
||||||
when(guild.getName()).thenReturn(GUILD_NAME);
|
|
||||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
|
||||||
when(warnedMember.getUser()).thenReturn(warnedSimpleUser);
|
|
||||||
when(templateService.renderEmbedTemplate(eq(WARN_LOG_TEMPLATE), warnDecayLogModelArgumentCaptor.capture(), eq(SERVER_ID))).thenReturn(messageToSend);
|
|
||||||
when(messageService.sendMessageToUser(eq(warnedMember.getUser()), any())).thenReturn(CompletableFuture.completedFuture(null));
|
|
||||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, WarningPostTarget.WARN_LOG, SERVER_ID)).thenReturn(CommandTestUtilities.messageFutureList());
|
|
||||||
when(templateService.renderTemplate(eq(WarnServiceBean.WARN_NOTIFICATION_TEMPLATE), notificationCaptor.capture(), eq(SERVER_ID))).thenReturn(NOTIFICATION_TEXT);
|
|
||||||
when(serverManagementService.loadOrCreate(SERVER_ID)).thenReturn(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupWarnings() {
|
|
||||||
when(firstWarning.getWarningUser()).thenReturn(warningUser);
|
|
||||||
when(secondWarning.getWarningUser()).thenReturn(warningUser);
|
|
||||||
when(warningUser.getServerReference()).thenReturn(server);
|
|
||||||
when(warningUser.getUserReference()).thenReturn(thirdAUser);
|
|
||||||
|
|
||||||
when(firstWarning.getWarnedUser()).thenReturn(firstWarnedUser);
|
|
||||||
when(firstWarnedUser.getServerReference()).thenReturn(server);
|
|
||||||
when(firstWarnedUser.getUserReference()).thenReturn(firstAUser);
|
|
||||||
when(secondWarning.getWarnedUser()).thenReturn(secondWarnedUser);
|
|
||||||
when(secondWarnedUser.getServerReference()).thenReturn(server);
|
|
||||||
when(secondWarnedUser.getUserReference()).thenReturn(secondAUser);
|
|
||||||
when(firstWarning.getWarnId()).thenReturn(new ServerSpecificId(SERVER_ID, WARN_ID));
|
|
||||||
when(secondWarning.getWarnId()).thenReturn(new ServerSpecificId(SERVER_ID, 9L));
|
|
||||||
when(server.getId()).thenReturn(SERVER_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupWarnDecay() {
|
|
||||||
setupWarnings();
|
|
||||||
SystemConfigProperty defaultDecayDays = Mockito.mock(SystemConfigProperty.class);
|
|
||||||
Long defaultDayCount = 4L;
|
|
||||||
when(defaultDecayDays.getLongValue()).thenReturn(defaultDayCount);
|
|
||||||
when(defaultConfigManagementService.getDefaultConfig(WarningDecayFeatureConfig.DECAY_DAYS_KEY)).thenReturn(defaultDecayDays);
|
|
||||||
when(configService.getLongValue(WarningDecayFeatureConfig.DECAY_DAYS_KEY, SERVER_ID, defaultDayCount)).thenReturn(5L);
|
|
||||||
List<Warning> warnings = Arrays.asList(firstWarning, secondWarning);
|
|
||||||
when(memberService.getMemberInServerAsync(warningUser)).thenReturn(CompletableFuture.completedFuture(warningMember));
|
|
||||||
when(memberService.getMemberInServerAsync(firstWarnedUser)).thenReturn(CompletableFuture.completedFuture(warnedMember));
|
|
||||||
when(memberService.getMemberInServerAsync(secondWarnedUser)).thenReturn(CompletableFuture.completedFuture(secondWarnedMember));
|
|
||||||
when(warnManagementService.getActiveWarningsInServerOlderThan(eq(server), any(Instant.class))).thenReturn(warnings);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service.management;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.AServerAChannelMessage;
|
|
||||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
|
||||||
import dev.sheldan.abstracto.moderation.repository.MuteRepository;
|
|
||||||
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.Instant;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class MuteManagementServiceBeanTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private MuteManagementServiceBean testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteRepository muteRepository;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private UserInServerManagementService userInServerManagementService;
|
|
||||||
|
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<Mute> muteArgumentCaptor;
|
|
||||||
|
|
||||||
private static final Long SERVER_ID = 1L;
|
|
||||||
private static final Long MUTE_ID = 2L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateMute() {
|
|
||||||
AServer server = Mockito.mock(AServer.class);
|
|
||||||
long messageId = 9L;
|
|
||||||
AChannel channel = Mockito.mock(AChannel.class);
|
|
||||||
AUserInAServer mutingUser = Mockito.mock(AUserInAServer.class);
|
|
||||||
AUserInAServer mutedUser = Mockito.mock(AUserInAServer.class);
|
|
||||||
AUser user = Mockito.mock(AUser.class);
|
|
||||||
when(mutedUser.getUserReference()).thenReturn(user);
|
|
||||||
when(mutedUser.getServerReference()).thenReturn(server);
|
|
||||||
AUser secondUser = Mockito.mock(AUser.class);
|
|
||||||
when(mutingUser.getUserReference()).thenReturn(secondUser);
|
|
||||||
String reason = "reason";
|
|
||||||
String triggerKey = "key";
|
|
||||||
Instant unMuteDate = Instant.now();
|
|
||||||
AServerAChannelMessage muteMessage = Mockito.mock(AServerAChannelMessage.class);
|
|
||||||
when(muteMessage.getMessageId()).thenReturn(messageId);
|
|
||||||
when(muteMessage.getServer()).thenReturn(server);
|
|
||||||
when(muteMessage.getChannel()).thenReturn(channel);
|
|
||||||
|
|
||||||
testUnit.createMute(mutedUser, mutingUser, reason, unMuteDate, muteMessage, triggerKey, 8L);
|
|
||||||
verify(muteRepository, times(1)).save(muteArgumentCaptor.capture());
|
|
||||||
Mute createdMute = muteArgumentCaptor.getValue();
|
|
||||||
Assert.assertEquals(reason, createdMute.getReason());
|
|
||||||
Assert.assertEquals(mutingUser, createdMute.getMutingUser());
|
|
||||||
Assert.assertEquals(mutedUser, createdMute.getMutedUser());
|
|
||||||
Assert.assertEquals(server, createdMute.getServer());
|
|
||||||
Assert.assertFalse(createdMute.getMuteEnded());
|
|
||||||
Assert.assertEquals(messageId, createdMute.getMessageId().longValue());
|
|
||||||
Assert.assertEquals(channel, createdMute.getMutingChannel());
|
|
||||||
Assert.assertEquals(unMuteDate, createdMute.getMuteTargetDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindMute() {
|
|
||||||
Mute mute = Mockito.mock(Mute.class);
|
|
||||||
ServerSpecificId muteId = Mockito.mock(ServerSpecificId.class);
|
|
||||||
when(mute.getMuteId()).thenReturn(muteId);
|
|
||||||
when(muteId.getId()).thenReturn(MUTE_ID);
|
|
||||||
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(MUTE_ID, SERVER_ID)).thenReturn(Optional.of(mute));
|
|
||||||
Optional<Mute> foundMuteOptional = testUnit.findMuteOptional(MUTE_ID, SERVER_ID);
|
|
||||||
Assert.assertTrue(foundMuteOptional.isPresent());
|
|
||||||
foundMuteOptional.ifPresent(foundMute -> Assert.assertEquals(MUTE_ID, foundMute.getMuteId().getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindNonExistingMute() {
|
|
||||||
when(muteRepository.findByMuteId_IdAndMuteId_ServerId(MUTE_ID, SERVER_ID)).thenReturn(Optional.empty());
|
|
||||||
Optional<Mute> foundMuteOptional = testUnit.findMuteOptional(MUTE_ID, SERVER_ID);
|
|
||||||
Assert.assertFalse(foundMuteOptional.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSaveMute() {
|
|
||||||
Mute mute = Mockito.mock(Mute.class);
|
|
||||||
testUnit.saveMute(mute);
|
|
||||||
verify(muteRepository, times(1)).save(mute);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMuteOfUser() {
|
|
||||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
|
||||||
Mute mute = Mockito.mock(Mute.class);
|
|
||||||
when(muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(mute);
|
|
||||||
Mute aMuteOf = testUnit.getAMuteOf(userInAServer);
|
|
||||||
Assert.assertEquals(mute, aMuteOf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMuteOfMember() {
|
|
||||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
|
||||||
Mute mute = Mockito.mock(Mute.class);
|
|
||||||
Member member = Mockito.mock(Member.class);
|
|
||||||
when(userInServerManagementService.loadOrCreateUser(member)).thenReturn(userInAServer);
|
|
||||||
when(muteRepository.findTopByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(mute);
|
|
||||||
Mute aMuteOf = testUnit.getAMuteOf(member);
|
|
||||||
Assert.assertEquals(mute, aMuteOf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAllMutesOf() {
|
|
||||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
|
||||||
Mute mute = Mockito.mock(Mute.class);
|
|
||||||
Mute mute2 = Mockito.mock(Mute.class);
|
|
||||||
when(muteRepository.findAllByMutedUserAndMuteEndedFalseOrderByMuteId_IdDesc(userInAServer)).thenReturn(Arrays.asList(mute, mute2));
|
|
||||||
List<Mute> allMutesOf = testUnit.getAllActiveMutesOf(userInAServer);
|
|
||||||
Assert.assertEquals(2, allMutesOf.size());
|
|
||||||
Assert.assertEquals(mute, allMutesOf.get(0));
|
|
||||||
Assert.assertEquals(mute2, allMutesOf.get(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHasActiveMute() {
|
|
||||||
checkExist(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHasNoActiveMute() {
|
|
||||||
checkExist(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkExist(boolean value) {
|
|
||||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
|
||||||
when(muteRepository.existsByMutedUserAndMuteEndedFalse(userInAServer)).thenReturn(value);
|
|
||||||
boolean result = testUnit.hasActiveMute(userInAServer);
|
|
||||||
Assert.assertEquals(value, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.moderation.service.management;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
|
||||||
import dev.sheldan.abstracto.moderation.model.database.MuteRole;
|
|
||||||
import dev.sheldan.abstracto.moderation.repository.MuteRoleRepository;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class MuteRoleManagementServiceBeanTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private MuteRoleManagementServiceBean testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private MuteRoleRepository muteRoleRepository;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AServer server;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRetrieveMuteRoleForServer() {
|
|
||||||
MuteRole role = Mockito.mock(MuteRole.class);
|
|
||||||
when(muteRoleRepository.findByRoleServer(server)).thenReturn(role);
|
|
||||||
MuteRole muteRole = testUnit.retrieveMuteRoleForServer(server);
|
|
||||||
Assert.assertEquals(role, muteRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testServeHasMuteRole() {
|
|
||||||
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(true);
|
|
||||||
Assert.assertTrue(testUnit.muteRoleForServerExists(server));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateMuteRoleForServer() {
|
|
||||||
ARole role = Mockito.mock(ARole.class);
|
|
||||||
ArgumentCaptor<MuteRole> muteRoleCaptor = ArgumentCaptor.forClass(MuteRole.class);
|
|
||||||
MuteRole savedRole = Mockito.mock(MuteRole.class);
|
|
||||||
when(muteRoleRepository.save(muteRoleCaptor.capture())).thenReturn(savedRole);
|
|
||||||
MuteRole muteRoleForServer = testUnit.createMuteRoleForServer(server, role);
|
|
||||||
Assert.assertEquals(savedRole, muteRoleForServer);
|
|
||||||
Assert.assertEquals(role, muteRoleCaptor.getValue().getRole());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRetrieveRolesForServer() {
|
|
||||||
List<MuteRole> existingRoles = Arrays.asList(Mockito.mock(MuteRole.class), Mockito.mock(MuteRole.class));
|
|
||||||
when(muteRoleRepository.findAllByRoleServer(server)).thenReturn(existingRoles);
|
|
||||||
List<MuteRole> foundRoles = testUnit.retrieveMuteRolesForServer(server);
|
|
||||||
Assert.assertEquals(existingRoles.size(), foundRoles.size());
|
|
||||||
for (int i = 0; i < existingRoles.size(); i++) {
|
|
||||||
MuteRole existingRole = existingRoles.get(i);
|
|
||||||
MuteRole foundRole = foundRoles.get(i);
|
|
||||||
Assert.assertEquals(existingRole, foundRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetMuteRoleWithoutPrevious() {
|
|
||||||
ARole role = Mockito.mock(ARole.class);
|
|
||||||
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(false);
|
|
||||||
ArgumentCaptor<MuteRole> muteRoleCaptor = ArgumentCaptor.forClass(MuteRole.class);
|
|
||||||
MuteRole savedRole = Mockito.mock(MuteRole.class);
|
|
||||||
when(muteRoleRepository.save(muteRoleCaptor.capture())).thenReturn(savedRole);
|
|
||||||
MuteRole muteRole = testUnit.setMuteRoleForServer(server, role);
|
|
||||||
Assert.assertEquals(savedRole, muteRole);
|
|
||||||
Assert.assertEquals(role, muteRoleCaptor.getValue().getRole());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetMuteRoleWithPrevious() {
|
|
||||||
ARole role = Mockito.mock(ARole.class);
|
|
||||||
when(muteRoleRepository.existsByRoleServer(server)).thenReturn(true);
|
|
||||||
MuteRole existingRole = Mockito.mock(MuteRole.class);
|
|
||||||
when(muteRoleRepository.findByRoleServer(server)).thenReturn(existingRole);
|
|
||||||
testUnit.setMuteRoleForServer(server, role);
|
|
||||||
verify(existingRole, times(1)).setRole(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.moderation.config;
|
|||||||
public class ModerationSlashCommandNames {
|
public class ModerationSlashCommandNames {
|
||||||
public static final String MODERATION = "moderation";
|
public static final String MODERATION = "moderation";
|
||||||
public static final String WARNINGS = "warnings";
|
public static final String WARNINGS = "warnings";
|
||||||
|
public static final String INFRACTIONS = "infractions";
|
||||||
public static final String USER_NOTES = "usernotes";
|
public static final String USER_NOTES = "usernotes";
|
||||||
public static final String MUTE = "mute";
|
public static final String MUTE = "mute";
|
||||||
public static final String WARN_DECAY = "warningdecay";
|
public static final String WARN_DECAY = "warningdecay";
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
public class ModerationFeatureConfig implements FeatureConfig {
|
public class ModerationFeatureConfig implements FeatureConfig {
|
||||||
|
|
||||||
|
public static final String BAN_INFRACTION_POINTS = "banInfractionPoints";
|
||||||
|
public static final String KICK_INFRACTION_POINTS = "kickInfractionPoints";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FeatureDefinition getFeature() {
|
public FeatureDefinition getFeature() {
|
||||||
return ModerationFeatureDefinition.MODERATION;
|
return ModerationFeatureDefinition.MODERATION;
|
||||||
@@ -22,4 +25,8 @@ public class ModerationFeatureConfig implements FeatureConfig {
|
|||||||
return Arrays.asList(ModerationPostTarget.BAN_LOG, ModerationPostTarget.KICK_LOG, ModerationPostTarget.UN_BAN_LOG);
|
return Arrays.asList(ModerationPostTarget.BAN_LOG, ModerationPostTarget.KICK_LOG, ModerationPostTarget.UN_BAN_LOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRequiredSystemConfigKeys() {
|
||||||
|
return Arrays.asList(KICK_INFRACTION_POINTS, BAN_INFRACTION_POINTS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package dev.sheldan.abstracto.moderation.config.feature;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
|
||||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||||
import dev.sheldan.abstracto.moderation.config.feature.mode.MutingMode;
|
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -14,6 +12,8 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
public class MutingFeatureConfig implements FeatureConfig {
|
public class MutingFeatureConfig implements FeatureConfig {
|
||||||
|
|
||||||
|
public static final String MUTE_INFRACTION_POINTS = "muteInfractionPoints";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FeatureDefinition getFeature() {
|
public FeatureDefinition getFeature() {
|
||||||
return ModerationFeatureDefinition.MUTING;
|
return ModerationFeatureDefinition.MUTING;
|
||||||
@@ -25,7 +25,7 @@ public class MutingFeatureConfig implements FeatureConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<FeatureMode> getAvailableModes() {
|
public List<String> getRequiredSystemConfigKeys() {
|
||||||
return Arrays.asList(MutingMode.MANUAL_UN_MUTE_LOGGING);
|
return Arrays.asList(MUTE_INFRACTION_POINTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package dev.sheldan.abstracto.moderation.config.feature;
|
|||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||||
|
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||||
|
import dev.sheldan.abstracto.moderation.config.feature.mode.ReportReactionMode;
|
||||||
import dev.sheldan.abstracto.moderation.config.posttarget.ReactionReportPostTarget;
|
import dev.sheldan.abstracto.moderation.config.posttarget.ReactionReportPostTarget;
|
||||||
import dev.sheldan.abstracto.moderation.service.ReactionReportService;
|
import dev.sheldan.abstracto.moderation.service.ReactionReportService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -33,4 +35,9 @@ public class ReportReactionFeatureConfig implements FeatureConfig {
|
|||||||
public List<String> getRequiredSystemConfigKeys() {
|
public List<String> getRequiredSystemConfigKeys() {
|
||||||
return Arrays.asList(ReactionReportService.REACTION_REPORT_COOLDOWN);
|
return Arrays.asList(ReactionReportService.REACTION_REPORT_COOLDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FeatureMode> getAvailableModes() {
|
||||||
|
return Arrays.asList(ReportReactionMode.SINGULAR_MESSAGE, ReportReactionMode.ANONYMOUS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user