mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-17 13:49:30 +00:00
Compare commits
24 Commits
abstracto-
...
abstracto-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b16cef0d3c | ||
|
|
cc55934ff2 | ||
|
|
168b4a52c8 | ||
|
|
73b5684a7e | ||
|
|
23ba9a88aa | ||
|
|
a5664946e1 | ||
|
|
ec16548cea | ||
|
|
9c9082034a | ||
|
|
1486a0e9c3 | ||
|
|
533f1afcd5 | ||
|
|
a6c3bb5aa2 | ||
|
|
5311cfcc2e | ||
|
|
ee7f9180dc | ||
|
|
3f67593ef4 | ||
|
|
0ccee3b211 | ||
|
|
86b9ccb164 | ||
|
|
bc1eb0b55f | ||
|
|
92a8b5ba64 | ||
|
|
7535b2e66d | ||
|
|
7117ac26d3 | ||
|
|
32056cd6b9 | ||
|
|
efd6c23713 | ||
|
|
794fc7ceac | ||
|
|
6b5a255aa8 |
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>anti-raid-impl</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>core-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>anti-raid-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/liquibase.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
|
||||
<id>liquibase</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<directory>${project.basedir}/src/main/resources/migrations</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.antiraid.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:antiRaid-config.properties")
|
||||
public class AntiRaidProperties {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.sheldan.abstracto.antiraid.listener;
|
||||
|
||||
import dev.sheldan.abstracto.antiraid.config.AntiRaidFeatureDefinition;
|
||||
import dev.sheldan.abstracto.antiraid.service.MassPingService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
|
||||
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.ChannelType;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MassPingMessageListener implements AsyncMessageReceivedListener {
|
||||
|
||||
@Autowired
|
||||
private MassPingService massPingService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||
Message message = model.getMessage();
|
||||
if(message.getAuthor().isBot() || message.isWebhookMessage() || !message.isFromGuild() || !message.isFromType(ChannelType.TEXT)) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
massPingService.processMessage(message);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return AntiRaidFeatureDefinition.ANTI_RAID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package dev.sheldan.abstracto.antiraid.service;
|
||||
|
||||
import dev.sheldan.abstracto.antiraid.config.AntiRaidPostTarget;
|
||||
import dev.sheldan.abstracto.antiraid.model.MassPingNotificationModel;
|
||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ConditionService;
|
||||
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.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MassPingServiceBean implements MassPingService {
|
||||
|
||||
private static final String MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY = "massPing_mute_notification";
|
||||
|
||||
private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL";
|
||||
private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId";
|
||||
private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level";
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private MuteService muteService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private MassPingServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private ConditionService conditionService;
|
||||
|
||||
@Value("${abstracto.massPing.maxAllowedMentions}")
|
||||
private Integer maxAllowedMentions;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> processMessage(Message message) {
|
||||
if(message.getMentionedMembers().size() > maxAllowedMentions) {
|
||||
Integer level = configService.getLongValueOrConfigDefault(MassPingService.MAX_AFFECTED_LEVEL_KEY, message.getGuild().getIdLong()).intValue();
|
||||
boolean allowed = allowedToMassMention(message, level);
|
||||
if(!allowed) {
|
||||
return muteService.muteMemberWithoutContext(message.getMember())
|
||||
.thenAccept(unused -> self.sendMassPingMuteNotification(message))
|
||||
.thenAccept(unused -> log.info("Muted member {} in server {} because of too many member mentions. (> {}).",
|
||||
message.getMember().getIdLong(), message.getGuild().getIdLong(), maxAllowedMentions));
|
||||
} else {
|
||||
log.info("User {} in server {} is allowed to mass mention, because of level (or lack of level configuration).",
|
||||
message.getMember().getIdLong(), message.getGuild().getIdLong());
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean allowedToMassMention(Message message, Integer level) {
|
||||
log.info("Checking if member {} is allowed to mention a lot of users in server {}.", message.getAuthor().getIdLong(), message.getGuild().getIdLong());
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(message.getMember());
|
||||
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
|
||||
parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level);
|
||||
ConditionContextInstance contextInstance = ConditionContextInstance
|
||||
.builder()
|
||||
.conditionName(LEVEL_CONDITION_NAME)
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
return conditionService.checkConditions(contextInstance);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendMassPingMuteNotification(Message message) {
|
||||
Member member = message.getMember();
|
||||
MassPingNotificationModel model = MassPingNotificationModel
|
||||
.builder()
|
||||
.messageLink(message.getJumpUrl())
|
||||
.mentionCount(message.getMentionedMembers().size())
|
||||
.messageContent(message.getContentRaw())
|
||||
.memberDisplay(MemberDisplay.fromMember(member))
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY, model, member.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, AntiRaidPostTarget.MASS_PING_LOG, member.getGuild().getIdLong()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
abstracto.featureFlags.antiRaid.featureName=antiRaid
|
||||
abstracto.featureFlags.antiRaid.enabled=false
|
||||
|
||||
abstracto.postTargets.massPingLog.name=massPingLog
|
||||
|
||||
abstracto.massPing.maxAllowedMentions=5
|
||||
|
||||
abstracto.systemConfigs.massPingMinLevel.name=massPingMinLevel
|
||||
abstracto.systemConfigs.massPingMinLevel.longValue=15
|
||||
@@ -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,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="feature.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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="anti_raid-feature-insertion">
|
||||
<insert tableName="feature">
|
||||
<column name="key" value="antiRaid"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?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" >
|
||||
</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="1.3.3/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>anti-raid-int</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>core-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.abstracto.antiraid.config;
|
||||
|
||||
import dev.sheldan.abstracto.antiraid.service.MassPingService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.MutingFeatureConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class AntiRaidFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Autowired
|
||||
private MutingFeatureConfig mutingFeatureConfig;
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return AntiRaidFeatureDefinition.ANTI_RAID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PostTargetEnum> getRequiredPostTargets() {
|
||||
return Arrays.asList(AntiRaidPostTarget.MASS_PING_LOG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredSystemConfigKeys() {
|
||||
return Arrays.asList(MassPingService.MAX_AFFECTED_LEVEL_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureConfig> getRequiredFeatures() {
|
||||
return Arrays.asList(mutingFeatureConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.antiraid.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum AntiRaidFeatureDefinition implements FeatureDefinition {
|
||||
ANTI_RAID("antiRaid");
|
||||
|
||||
private String key;
|
||||
|
||||
AntiRaidFeatureDefinition(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.antiraid.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum AntiRaidPostTarget implements PostTargetEnum {
|
||||
MASS_PING_LOG("massPingLog");
|
||||
|
||||
private String key;
|
||||
|
||||
AntiRaidPostTarget(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.abstracto.antiraid.model;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class MassPingNotificationModel {
|
||||
private MemberDisplay memberDisplay;
|
||||
private String messageContent;
|
||||
private String messageLink;
|
||||
private Integer mentionCount;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.antiraid.service;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface MassPingService {
|
||||
String MAX_AFFECTED_LEVEL_KEY = "massPingMinLevel";
|
||||
CompletableFuture<Void> processMessage(Message message);
|
||||
}
|
||||
17
abstracto-application/abstracto-modules/anti-raid/pom.xml
Normal file
17
abstracto-application/abstracto-modules/anti-raid/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>anti-raid-int</module>
|
||||
<module>anti-raid-impl</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.assignableroles.command;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
@@ -41,11 +42,15 @@ public class CreateAssignableRolePost extends AbstractConditionableCommand {
|
||||
String name = (String) parameters.get(0);
|
||||
TextChannel channel = (TextChannel) parameters.get(1);
|
||||
String text = (String) parameters.get(2);
|
||||
AssignableRolePlaceType type = AssignableRolePlaceType.DEFAULT;
|
||||
if(parameters.size() > 3) {
|
||||
type = (AssignableRolePlaceType) parameters.get(3);
|
||||
}
|
||||
if(!channel.getGuild().equals(commandContext.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
AChannel chosenChannel = channelManagementService.loadChannel(channel.getIdLong());
|
||||
service.createAssignableRolePlace(name, chosenChannel, text);
|
||||
service.createAssignableRolePlace(name, chosenChannel, text, type);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@@ -54,10 +59,11 @@ public class CreateAssignableRolePost extends AbstractConditionableCommand {
|
||||
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
|
||||
Parameter rolePostName = Parameter.builder().name("name").validators(rolePlaceNameValidator).type(String.class).templated(true).build();
|
||||
Parameter channel = Parameter.builder().name("channel").type(TextChannel.class).templated(true).build();
|
||||
Parameter type = Parameter.builder().name("type").type(AssignableRolePlaceType.class).templated(true).optional(true).build();
|
||||
List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
|
||||
Parameter text = Parameter.builder().name("text").validators(rolePlaceDescriptionValidator).type(String.class).remainder(true).optional(true).templated(true).build();
|
||||
Parameter text = Parameter.builder().name("text").validators(rolePlaceDescriptionValidator).type(String.class).templated(true).build();
|
||||
List<String> aliases = Arrays.asList("crRPl", "crAssRoPl");
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName, channel, text);
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName, channel, text, type);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("createAssignableRolePlace")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.assignableroles.command;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig;
|
||||
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
@@ -9,8 +10,9 @@ 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.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -24,21 +26,24 @@ import java.util.concurrent.CompletableFuture;
|
||||
@Component
|
||||
public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand {
|
||||
|
||||
|
||||
@Autowired
|
||||
private AssignableRolePlaceService service;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
public static final String ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY = "assignable_roles_config_post";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String name = (String) parameters.get(0);
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
// TODO refactor to return something to be posted in this command here instead of relying it to be posted somewhere else
|
||||
return service.showAssignablePlaceConfig(server, name, commandContext.getChannel())
|
||||
.thenApply(unused -> CommandResult.fromIgnored());
|
||||
AssignableRolePlaceConfig config = service.getAssignableRolePlaceConfig(commandContext.getGuild(), name);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY, config, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,7 +56,7 @@ public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.causesReaction(true)
|
||||
.causesReaction(false)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.assignableroles.command;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview;
|
||||
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
@@ -9,7 +10,9 @@ 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.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -28,11 +31,16 @@ public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
public static final String ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY = "assignable_role_places_overview";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
return service.showAllAssignableRolePlaces(server, commandContext.getChannel())
|
||||
.thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
AssignablePlaceOverview model = service.getAssignableRolePlaceOverview(commandContext.getGuild());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,7 +50,6 @@ public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
|
||||
.name("showAssignableRolePlaces")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -2,11 +2,13 @@ package dev.sheldan.abstracto.assignableroles.listener;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
|
||||
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotFoundException;
|
||||
import dev.sheldan.abstracto.assignableroles.exception.BoosterAssignableRolePlaceMemberNotBoostingException;
|
||||
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
|
||||
import dev.sheldan.abstracto.assignableroles.model.AssignableRolePlacePayload;
|
||||
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRoleSuccessNotificationModel;
|
||||
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionServiceBean;
|
||||
@@ -73,9 +75,10 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ButtonClickEvent event = model.getEvent();
|
||||
AssignableRolePlacePayload payload = (AssignableRolePlacePayload) model.getDeserializedPayload();
|
||||
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
|
||||
if(event.getGuild() != null && event.getMember() != null) {
|
||||
Member member = event.getMember();
|
||||
if(event.getGuild() != null && member != null) {
|
||||
AssignableRolePlacePayload payload = (AssignableRolePlacePayload) model.getDeserializedPayload();
|
||||
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
|
||||
Guild guild = event.getGuild();
|
||||
List<Role> removedRoles = new ArrayList<>();
|
||||
Role roleById = guild.getRoleById(payload.getRoleId());
|
||||
@@ -88,19 +91,25 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
throw new AssignableRoleNotFoundException(payload.getRoleId());
|
||||
}
|
||||
if(roleById != null) {
|
||||
boolean memberHasRole = event
|
||||
.getMember()
|
||||
boolean memberHasRole = member
|
||||
.getRoles()
|
||||
.stream()
|
||||
.anyMatch(memberRole -> memberRole.getIdLong() == payload.getRoleId());
|
||||
if(!memberHasRole) {
|
||||
if(place.getType().equals(AssignableRolePlaceType.BOOSTER) && member.getTimeBoosted() == null) {
|
||||
assignableRoleService.assignableRoleConditionFailure();
|
||||
throw new BoosterAssignableRolePlaceMemberNotBoostingException();
|
||||
}
|
||||
AssignableRole assignableRole = assignableRoleOptional.get();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember());
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
if(!assignableRole.getConditions().isEmpty()) {
|
||||
log.debug("Evaluating {} conditions for assignable role {}.", assignableRole.getConditions().size(), assignableRole.getId());
|
||||
AssignableRoleConditionResult conditionResult =
|
||||
assignableRoleConditionServiceBean.evaluateConditions(assignableRole.getConditions(), aUserInAServer, roleById);
|
||||
if(!conditionResult.getFulfilled()) {
|
||||
log.info("One condition failed to be fulfilled - notifying user.");
|
||||
self.notifyUserAboutConditionFail(model, event.getInteraction(), conditionResult.getModel());
|
||||
assignableRoleService.assignableRoleConditionFailure();
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
}
|
||||
@@ -116,9 +125,10 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
.map(roleOfUser -> guild.getRoleById(roleOfUser.getRole().getId()))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
log.info("Removing {} because of unique role configuration in place {}.", rolesToRemove.size(), place.getId());
|
||||
removedRoles.addAll(rolesToRemove);
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
rolesToRemove.forEach(roleToRemove -> removalFutures.add(roleService.removeRoleFromUserAsync(event.getMember(), roleToRemove)));
|
||||
rolesToRemove.forEach(roleToRemove -> removalFutures.add(roleService.removeRoleFromUserAsync(member, roleToRemove)));
|
||||
removalFuture = new CompletableFutureList<>(removalFutures).getMainFuture();
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
@@ -126,29 +136,29 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture<Void> roleAdditionFuture = roleService.addRoleToMemberAsync(event.getMember(), roleById);
|
||||
CompletableFuture<Void> roleAdditionFuture = assignableRoleService.assignAssignableRoleToUser(roleById, member);
|
||||
CompletableFuture.allOf(removalFuture, roleAdditionFuture).whenComplete((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.error("Failed to either add or remove roles for assignable role place {} in server {}.", payload.getPlaceId(), guild.getIdLong());
|
||||
}
|
||||
if(!roleAdditionFuture.isCompletedExceptionally()) {
|
||||
log.info("Added role {} to member {} in server {} for assignable role interaction {} on component {}.",
|
||||
roleById.getId(), event.getMember().getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
|
||||
roleById.getId(), member.getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
|
||||
self.notifyUser(model, true, roleById, event.getInteraction(), removedRoles).thenAccept(unused1 -> {
|
||||
log.info("Persisting adding assignable role update for user {} in server {} of role {}.", event.getMember().getIdLong(), guild.getIdLong(), roleById.getId());
|
||||
self.persistAssignableUser(event.getMember(), payload, false);
|
||||
log.info("Persisting adding assignable role update for user {} in server {} of role {}.", member.getIdLong(), guild.getIdLong(), roleById.getId());
|
||||
self.persistAssignableUser(member, payload, false);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
roleService.removeRoleFromUserAsync(event.getMember(), roleById)
|
||||
assignableRoleService.removeAssignableRoleFromUser(roleById, member)
|
||||
.thenAccept(unused -> {
|
||||
self.notifyUser(model, false, roleById, event.getInteraction(), new ArrayList<>());
|
||||
log.info("Removed role {} from member {} in server {} for assignable role interaction {} on component {}.",
|
||||
roleById.getId(), event.getMember().getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
|
||||
roleById.getId(), member.getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
|
||||
}).thenAccept(unused -> {
|
||||
log.info("Persisting remove assignable role update for user {} in server {} of role {}.", event.getMember().getIdLong(), guild.getIdLong(), roleById.getId());
|
||||
self.persistAssignableUser(event.getMember(), payload, true);
|
||||
log.info("Persisting remove assignable role update for user {} in server {} of role {}.", member.getIdLong(), guild.getIdLong(), roleById.getId());
|
||||
self.persistAssignableUser(member, payload, true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -183,6 +193,8 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> notifyUser(ButtonClickedListenerModel model, boolean roleAdded, Role role, ButtonInteraction buttonInteraction, List<Role> removedRoles) {
|
||||
log.info("Notifying user {} in server {} in channel {} about role change with role {}.",
|
||||
buttonInteraction.getUser().getIdLong(), buttonInteraction.getGuild().getIdLong(), buttonInteraction.getChannel().getIdLong(), role.getId());
|
||||
AssignableRoleSuccessNotificationModel notificationModel = AssignableRoleSuccessNotificationModel
|
||||
.builder()
|
||||
.added(roleAdded)
|
||||
@@ -196,6 +208,8 @@ public class AssignableRoleButtonClickedListener implements ButtonClickedListene
|
||||
@Transactional
|
||||
public CompletableFuture<Void> notifyUserAboutConditionFail(ButtonClickedListenerModel model, ButtonInteraction buttonInteraction,
|
||||
AssignableRolePlaceConditionModel conditionModel) {
|
||||
log.info("Notifying user {} in server {} in channel {} about failed condition.", buttonInteraction.getUser().getIdLong(),
|
||||
buttonInteraction.getGuild().getIdLong(), buttonInteraction.getChannel().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(
|
||||
interactionService.sendMessageToInteraction("assignable_role_condition_notification", conditionModel, buttonInteraction.getHook())) ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package dev.sheldan.abstracto.assignableroles.listener;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleService;
|
||||
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleManagementService;
|
||||
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMemberBoostTimeUpdateListener;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.listener.BoostTimeUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AssignableRolePlaceBoostTimeUpdateListener implements AsyncMemberBoostTimeUpdateListener {
|
||||
|
||||
@Autowired
|
||||
private AssignedRoleUserManagementService assignedRoleUserManagementService;
|
||||
|
||||
@Autowired
|
||||
private AssignableRoleManagementService assignableRoleManagementService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private AssignableRoleService assignableRoleService;
|
||||
|
||||
@Autowired
|
||||
private AssignableRolePlaceBoostTimeUpdateListener self;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(BoostTimeUpdatedModel model) {
|
||||
Member member = model.getMember();
|
||||
if(member.getTimeBoosted() == null) {
|
||||
removeAssignedBoosterRoles(member);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
private void removeAssignedBoosterRoles(Member member) {
|
||||
log.info("Member {} in server {} stopped boosting.", member.getIdLong(), member.getGuild().getIdLong());
|
||||
ServerUser serverUser = ServerUser.fromMember(member);
|
||||
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementService.findByUserInServerOptional(serverUser);
|
||||
if(assignedRoleUserOptional.isPresent()) {
|
||||
AssignedRoleUser assignedRoleUser = assignedRoleUserOptional.get();
|
||||
List<AssignableRole> boosterRoles = assignableRoleManagementService.getAssignableRolesFromAssignableUserWithPlaceType(assignedRoleUser, AssignableRolePlaceType.BOOSTER);
|
||||
if(!boosterRoles.isEmpty()) {
|
||||
log.info("Removing {} assignable role mappings.", boosterRoles.size());
|
||||
Guild guild = member.getGuild();
|
||||
List<Role> actualRolesToDelete = boosterRoles
|
||||
.stream()
|
||||
.map(assignableRole -> guild.getRoleById(assignableRole.getRole().getId()))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
log.debug("Which translated to {} roles in reality.", actualRolesToDelete.size());
|
||||
List<CompletableFuture<Void>> list = new ArrayList<>();
|
||||
actualRolesToDelete.forEach(role -> list.add(roleService.removeRoleFromUserAsync(member, role)));
|
||||
FutureUtils.toSingleFutureGeneric(list)
|
||||
.thenAccept(unused -> self.clearPersistedBoosterAssignableRoles(member))
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("One or more roles might have failed to remove. ", throwable);
|
||||
self.clearPersistedBoosterAssignableRoles(member);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
log.info("Member {} in server {} did not have boost roles - doing nothing.", member.getIdLong(), member.getGuild().getIdLong());
|
||||
}
|
||||
} else {
|
||||
log.info("Member (ID {}) in server (ID: {}), who was not tracked via assignable roles, stopped boosting - doing nothing.",
|
||||
member.getIdLong(), member.getGuild().getIdLong());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void clearPersistedBoosterAssignableRoles(Member member) {
|
||||
ServerUser serverUser = ServerUser.fromMember(member);
|
||||
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementService.findByUserInServerOptional(serverUser);
|
||||
if(assignedRoleUserOptional.isPresent()) {
|
||||
AssignedRoleUser assignedRoleUser = assignedRoleUserOptional.get();
|
||||
List<AssignableRole> boosterRoles = assignableRoleManagementService.getAssignableRolesFromAssignableUserWithPlaceType(assignedRoleUser, AssignableRolePlaceType.BOOSTER);
|
||||
assignableRoleService.removeAssignableRolesFromAssignableRoleUser(boosterRoles, assignedRoleUser);
|
||||
} else {
|
||||
log.warn("No assigned role user found for member {} in server {}.", member.getIdLong(), member.getGuild().getIdLong());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
package dev.sheldan.abstracto.assignableroles.repository;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Repository to manage the access to the table managed by {@link AssignableRole assignableRole}
|
||||
*/
|
||||
@Repository
|
||||
public interface AssignableRoleRepository extends JpaRepository<AssignableRole, Long> {
|
||||
List<AssignableRole> findByAssignedUsersContainingAndAssignablePlace_Type(AssignedRoleUser roleUser, AssignableRolePlaceType type);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -27,6 +28,7 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AssignableRoleConditionServiceBean implements AssignableRoleConditionService {
|
||||
|
||||
@Autowired
|
||||
@@ -55,12 +57,15 @@ public class AssignableRoleConditionServiceBean implements AssignableRoleConditi
|
||||
|
||||
@Override
|
||||
public AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, AUserInAServer aUserInAServer, Role role) {
|
||||
log.debug("Evaluating {} conditions for role {}.", conditions.size(), role.getId());
|
||||
for (AssignableRoleCondition condition : conditions) {
|
||||
if(assignableRoleConditionEvaluators != null) {
|
||||
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(condition.getType());
|
||||
if(evaluatorOptional.isPresent()) {
|
||||
AssignableRoleConditionEvaluator evaluator = evaluatorOptional.get();
|
||||
log.debug("Evaluating condition {} with evaluator {}.", condition.getType(), evaluator.getClass());
|
||||
if(!evaluator.fulfillsCondition(condition, aUserInAServer)) {
|
||||
log.info("Condition {} failed for role {} in server {}.", condition.getType(), role.getId(), aUserInAServer.getServerReference().getId());
|
||||
return AssignableRoleConditionResult.fromFail(condition.getType(), evaluator.createNotificationModel(condition, role));
|
||||
}
|
||||
}
|
||||
@@ -94,6 +99,7 @@ public class AssignableRoleConditionServiceBean implements AssignableRoleConditi
|
||||
if(assignableRoleConditionManagementService.findAssignableRoleCondition(assignableRole, type).isPresent()) {
|
||||
throw new AssignableRoleConditionAlreadyExistsException();
|
||||
}
|
||||
log.info("Creating new condition for role {} in place {} in server {}.", place.getId(), role.getId(), role.getGuild().getIdLong());
|
||||
return assignableRoleConditionManagementService.createAssignableRoleCondition(assignableRole, type, value);
|
||||
}
|
||||
|
||||
@@ -106,6 +112,7 @@ public class AssignableRoleConditionServiceBean implements AssignableRoleConditi
|
||||
if(!existingCondition.isPresent()) {
|
||||
throw new AssignableRoleConditionDoesNotExistException();
|
||||
}
|
||||
log.info("Deleting assignable role condition on place {} for role {} in server {}.", place.getId(), role.getId(), role.getGuild().getIdLong());
|
||||
existingCondition.ifPresent(condition -> assignableRoleConditionManagementService.deleteAssignableRoleCondition(condition));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.assignableroles.exception.*;
|
||||
import dev.sheldan.abstracto.assignableroles.model.AssignableRolePlacePayload;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.*;
|
||||
import dev.sheldan.abstracto.assignableroles.service.management.*;
|
||||
import dev.sheldan.abstracto.core.command.exception.CommandParameterKeyValueWrongTypeException;
|
||||
@@ -21,7 +22,6 @@ import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.*;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.interactions.components.ButtonStyle;
|
||||
@@ -38,9 +38,7 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class AssignableRolePlaceServiceBean implements AssignableRolePlaceService {
|
||||
|
||||
public static final String ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY = "assignable_roles_config_post";
|
||||
public static final String ASSIGNABLE_ROLES_POST_TEMPLATE_KEY = "assignable_roles_post";
|
||||
public static final String ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY = "assignable_role_places_overview";
|
||||
public static final int MAX_ASSIGNABLE_ROLES_PER_POST = ComponentService.MAX_BUTTONS_PER_ROW * 5;
|
||||
public static final String ASSIGNABLE_ROLE_COMPONENT_ORIGIN = "assignableRoleButton";
|
||||
@Autowired
|
||||
@@ -85,12 +83,18 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
@Autowired
|
||||
private AssignableRoleConditionService assignableRoleConditionService;
|
||||
|
||||
@Autowired
|
||||
private AssignedRoleUserManagementServiceBean assignedRoleUserManagementServiceBean;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public void createAssignableRolePlace(String name, AChannel channel, String text) {
|
||||
public void createAssignableRolePlace(String name, AChannel channel, String text, AssignableRolePlaceType type) {
|
||||
if (rolePlaceManagementService.doesPlaceExist(channel.getServer(), name)) {
|
||||
throw new AssignableRolePlaceAlreadyExistsException(name);
|
||||
}
|
||||
rolePlaceManagementService.createPlace(name, channel, text);
|
||||
rolePlaceManagementService.createPlace(name, channel, text, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,6 +102,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
public CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote fakeEmote, String description) {
|
||||
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, placeName);
|
||||
if (assignableRolePlace.getAssignableRoles().size() > MAX_ASSIGNABLE_ROLES_PER_POST) {
|
||||
log.info("Assignable role place {} has already {} roles. Not possible to add more.", assignableRolePlace.getId(), assignableRolePlace.getAssignableRoles().size());
|
||||
throw new AssignableRolePlaceMaximumRolesException();
|
||||
}
|
||||
if (assignableRolePlace.getAssignableRoles().stream().anyMatch(assignableRole -> assignableRole.getRole().getId().equals(role.getIdLong()))) {
|
||||
@@ -113,16 +118,17 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
throw new EmoteNotUsableException(fakeEmote.getEmote());
|
||||
}
|
||||
}
|
||||
log.debug("There are already message posts on for the assignable role place {}.", assignableRolePlace.getId());
|
||||
Optional<TextChannel> channelOptional = channelService.getTextChannelFromServerOptional(server.getId(), assignableRolePlace.getChannel().getId());
|
||||
if (channelOptional.isPresent()) {
|
||||
TextChannel textChannel = channelOptional.get();
|
||||
String buttonId = componentService.generateComponentId();
|
||||
String emoteMarkdown = fakeEmote != null ? fakeEmote.getEmoteRepr() : null;
|
||||
if (assignableRolePlace.getMessageId() != null) {
|
||||
return componentService.addButtonToMessage(assignableRolePlace.getMessageId(), textChannel, buttonId, description, emoteMarkdown, ButtonStyle.PRIMARY)
|
||||
log.debug("Assignable role place {} has already message post with ID {} - updating.", assignableRolePlace.getId(), assignableRolePlace.getMessageId());
|
||||
return componentService.addButtonToMessage(assignableRolePlace.getMessageId(), textChannel, buttonId, description, emoteMarkdown, ButtonStyle.SECONDARY)
|
||||
.thenAccept(message -> self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId));
|
||||
} else {
|
||||
log.info("Assignable role place {} is not yet setup - only adding role to the database.", assignableRolePlace.getId());
|
||||
self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
@@ -134,6 +140,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
@Transactional
|
||||
public void persistAssignableRoleAddition(Long placeId, Role role, String description, FullEmote fakeEmote, String componentId) {
|
||||
AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId);
|
||||
log.info("Adding role {} to assignable role place {} with component ID {}.", role.getId(), place.getId(), componentId);
|
||||
ComponentPayload payload = persistButtonCallback(place, componentId, role.getIdLong());
|
||||
assignableRoleManagementServiceBean.addRoleToPlace(fakeEmote, role, description, place, payload);
|
||||
}
|
||||
@@ -144,6 +151,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
Long assignableRolePlaceId = assignableRolePlace.getId();
|
||||
for (AssignableRole assignableRole : assignableRolePlace.getAssignableRoles()) {
|
||||
if (assignableRole.getRole().getId().equals(role.getId())) {
|
||||
log.info("Found {} role to be removed - removing button from place.", role.getId());
|
||||
// TODO we might want to actually remove all the assigned roles as well
|
||||
return removeButtonFromAssignableRolePlace(assignableRole, assignableRolePlace).thenAccept(aVoid ->
|
||||
self.deleteAssignableRoleFromPlace(assignableRolePlaceId, assignableRole.getId())
|
||||
);
|
||||
@@ -154,9 +163,12 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
|
||||
private CompletableFuture<Void> removeButtonFromAssignableRolePlace(AssignableRole assignableRole, AssignableRolePlace assignableRolePlace) {
|
||||
String componentId = assignableRole.getComponentPayload().getId();
|
||||
log.debug("Component ID to remove {} for role {}", componentId, assignableRole.getRole().getId());
|
||||
return channelService.retrieveMessageInChannel(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId())
|
||||
.thenCompose(message ->
|
||||
componentService.removeComponentWithId(message, componentId, true)
|
||||
.thenCompose(message -> {
|
||||
log.debug("Updating message {} to remove component with ID {}.", message.getIdLong(), componentId);
|
||||
return componentService.removeComponentWithId(message, componentId, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -171,6 +183,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
.findAny();
|
||||
roleToRemoveOptional.ifPresent(assignableRole -> {
|
||||
ComponentPayload componentPayload = assignableRole.getComponentPayload();
|
||||
assignedRoleUserManagementServiceBean.removeAssignedRoleFromUsers(assignableRole);
|
||||
assignableRoleManagementServiceBean.deleteAssignableRole(assignableRole);
|
||||
componentPayloadManagementService.deletePayload(componentPayload);
|
||||
});
|
||||
@@ -232,8 +245,10 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
|
||||
private CompletableFuture<Void> deleteExistingMessagePostsForPlace(AssignableRolePlace assignableRolePlace) {
|
||||
if (assignableRolePlace.getMessageId() != null) {
|
||||
log.info("Deleting old message {} for assignable role place {}.", assignableRolePlace.getMessageId(), assignableRolePlace.getId());
|
||||
return messageService.deleteMessageInChannelInServer(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId());
|
||||
} else {
|
||||
log.info("Assignable role place {} was not yet set up - no message ID tracked.", assignableRolePlace.getMessageId());
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
@@ -299,12 +314,11 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> showAssignablePlaceConfig(AServer server, String name, TextChannel channel) {
|
||||
Guild guild = guildService.getGuildById(server.getId());
|
||||
public AssignableRolePlaceConfig getAssignableRolePlaceConfig(Guild guild, String name) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
|
||||
log.info("Showing assignable role place config for place {} in channel {} on server {}.", place.getId(), channel.getId(), server.getId());
|
||||
AssignableRolePlaceConfig configModel = convertPlaceToAssignableRolePlaceConfig(guild, place);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY, configModel, channel));
|
||||
log.info("Generating assignable role place config for place {} on server {}.", place.getId(), guild.getIdLong());
|
||||
return convertPlaceToAssignableRolePlaceConfig(guild, place);
|
||||
}
|
||||
|
||||
private AssignableRolePlaceConfig convertPlaceToAssignableRolePlaceConfig(Guild guild, AssignableRolePlace place) {
|
||||
@@ -326,6 +340,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
return AssignableRolePlaceConfig
|
||||
.builder()
|
||||
.roles(roles)
|
||||
.type(place.getType())
|
||||
.placeName(place.getKey())
|
||||
.placeText(place.getText())
|
||||
.uniqueRoles(place.getUniqueRoles())
|
||||
@@ -336,6 +351,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
@Override
|
||||
public CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel) {
|
||||
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
|
||||
log.info("Moving assignable role place {} from channel {} to channel {} in guild {}.",
|
||||
place.getId(), place.getChannel().getId(), newChannel.getId(), newChannel.getGuild().getIdLong());
|
||||
CompletableFuture<Void> oldPostDeletionFuture = deleteExistingMessagePostsForPlace(place);
|
||||
Long serverId = server.getId();
|
||||
Long assignablePlaceId = place.getId();
|
||||
@@ -363,13 +380,14 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
@Transactional
|
||||
public void updateAssignableRolePlaceChannel(String name, TextChannel textChannel) {
|
||||
AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong());
|
||||
log.info("Setting assignable role place to channel {}.", textChannel.getIdLong());
|
||||
rolePlaceManagementService.moveAssignableRolePlace(name, channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteAssignableRolePlace(AServer server, String name) {
|
||||
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
|
||||
|
||||
log.info("Deleting assignable role place {}.", place.getId());
|
||||
Long placeId = place.getId();
|
||||
CompletableFuture<Void> deleteFuture = deleteExistingMessagePostsForPlace(place);
|
||||
return deleteFuture.thenAccept(unused -> self.deleteAssignableRolePlaceInDatabase(placeId));
|
||||
@@ -405,25 +423,24 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> showAllAssignableRolePlaces(AServer server, TextChannel channel) {
|
||||
public AssignablePlaceOverview getAssignableRolePlaceOverview(Guild guild) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
List<AssignableRolePlace> assignableRolePlaces = rolePlaceManagementService.findAllByServer(server);
|
||||
Guild guild = channel.getGuild();
|
||||
List<AssignableRolePlaceConfig> placeConfigs = assignableRolePlaces
|
||||
.stream()
|
||||
.map(place -> convertPlaceToAssignableRolePlaceConfig(guild, place))
|
||||
.collect(Collectors.toList());
|
||||
AssignablePlaceOverview overViewModel = AssignablePlaceOverview
|
||||
log.info("Showing overview over all assignable role places for server {}.", server.getId());
|
||||
return AssignablePlaceOverview
|
||||
.builder()
|
||||
.places(placeConfigs)
|
||||
.build();
|
||||
log.info("Showing overview over all assignable role places for server {} in channel {}.", server.getId(), channel.getId());
|
||||
List<CompletableFuture<Message>> promises = channelService.sendEmbedTemplateInTextChannelList(ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY, overViewModel, channel);
|
||||
return CompletableFuture.allOf(promises.toArray(new CompletableFuture[0]));
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendAssignablePostMessage(AssignableRolePlace place, TextChannel channel) {
|
||||
AssignablePostMessage model = prepareAssignablePostMessageModel(place);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ASSIGNABLE_ROLES_POST_TEMPLATE_KEY, model, place.getServer().getId());
|
||||
log.info("Sending message for assignable role place {}.", place.getId());
|
||||
CompletableFuture<Message> postFuture = channelService.sendMessageToSendToChannel(messageToSend, channel).get(0);
|
||||
Long placeId = model.getPlaceId();
|
||||
return postFuture.thenCompose(unused -> {
|
||||
@@ -443,6 +460,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
public void persistAssignablePlaceMessageId(Long placeId, CompletableFuture<Message> messageFuture) {
|
||||
AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId);
|
||||
Message message = messageFuture.join();
|
||||
log.info("Setting message ID of assignable role place {} to {}.", placeId, message.getIdLong());
|
||||
place.setMessageId(message.getIdLong());
|
||||
}
|
||||
|
||||
@@ -491,7 +509,6 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
log.info("Sending assignable role place posts for place {} in channel {} in server {}.", assignableRolePlace.getId(), channel.getId(), serverId);
|
||||
return sendAssignablePostMessage(assignableRolePlace, channel);
|
||||
} else {
|
||||
log.warn("Channel to create assignable role post in does not exist.");
|
||||
throw new AssignableRolePlaceChannelDoesNotExistException(assignableRolePlace.getChannel().getId(), assignableRolePlace.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -71,14 +72,36 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
.tagList(Arrays.asList(MetricTag.getTag(ACTION, "removed")))
|
||||
.build();
|
||||
|
||||
private static final CounterMetric ASSIGNABLE_ROLES_CONDITION_FAILED =
|
||||
CounterMetric
|
||||
.builder()
|
||||
.name(ASSIGNABLE_ROLES_METRIC)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(ACTION, "condition")))
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, Member member) {
|
||||
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
|
||||
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
|
||||
log.info("Assigning role {} to member {} in server {}.", assignableRoleId, member.getId(), member.getGuild().getId());
|
||||
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
|
||||
return roleService.addRoleToMemberAsync(member, role.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> assignAssignableRoleToUser(Role role, Member member) {
|
||||
return assignRoleToUser(role.getIdLong(), member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignableRoleConditionFailure() {
|
||||
metricService.incrementCounter(ASSIGNABLE_ROLES_CONDITION_FAILED);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> assignRoleToUser(Long roleId, Member member) {
|
||||
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
|
||||
return roleService.addRoleToMemberAsync(member, roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllRolesOfUserInPlace(AssignableRolePlace place, AUserInAServer userInAServer) {
|
||||
Optional<AssignedRoleUser> userOptional = assignedRoleUserManagementServiceBean.findByUserInServerOptional(userInAServer);
|
||||
@@ -102,8 +125,17 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
@Override
|
||||
public CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, Member member) {
|
||||
log.info("Removing assignable role {} from user {} in server {}.", assignableRole.getId(), member.getId(), member.getGuild().getId());
|
||||
return removeRoleFromUser(assignableRole.getRole().getId(), member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeAssignableRoleFromUser(Role role, Member member) {
|
||||
return removeRoleFromUser(role.getIdLong(), member);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> removeRoleFromUser(Long roleId, Member member) {
|
||||
metricService.incrementCounter(ASSIGNABLE_ROLES_REMOVED);
|
||||
return roleService.removeRoleFromMemberAsync(member, assignableRole.getRole());
|
||||
return roleService.removeRoleFromMemberAsync(member, roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,9 +179,17 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
|
||||
throw new AssignableRoleNotFoundException(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssignableRolesFromAssignableRoleUser(List<AssignableRole> roles, AssignedRoleUser roleUser) {
|
||||
log.info("Removing {} assignable roles from user {} in server {}.", roles.size(), roleUser.getUser().getUserReference().getId(),
|
||||
roleUser.getUser().getServerReference().getId());
|
||||
roles.forEach(assignableRole -> assignedRoleUserManagementServiceBean.removeAssignedRoleFromUser(assignableRole, roleUser));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(ASSIGNABLE_ROLES_ASSIGNED, "Assignable roles assigned.");
|
||||
metricService.registerCounter(ASSIGNABLE_ROLES_REMOVED, "Assignable roles removed.");
|
||||
metricService.registerCounter(ASSIGNABLE_ROLES_CONDITION_FAILED, "Assignable roles failed to assign because of condition.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleCondi
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
|
||||
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleConditionRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AssignableRoleConditionManagementServiceBean implements AssignableRoleConditionManagementService {
|
||||
|
||||
@Autowired
|
||||
@@ -23,12 +25,14 @@ public class AssignableRoleConditionManagementServiceBean implements AssignableR
|
||||
.type(type)
|
||||
.conditionValue(value)
|
||||
.build();
|
||||
log.info("Creating condition of type {} for assignable role {}", assignableRole.getId(), type);
|
||||
assignableRole.getConditions().add(condition);
|
||||
return repository.save(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAssignableRoleCondition(AssignableRoleCondition condition) {
|
||||
log.info("Deleting condition {}.", condition.getId());
|
||||
repository.delete(condition);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package dev.sheldan.abstracto.assignableroles.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleRepository;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.FullEmote;
|
||||
@@ -15,6 +17,8 @@ import net.dv8tion.jda.api.entities.Role;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AssignableRoleManagementServiceBean implements AssignableRoleManagementService {
|
||||
@@ -51,8 +55,6 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
|
||||
return roleToAdd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public AssignableRole getByAssignableRoleId(Long assignableRoleId) {
|
||||
return repository.findById(assignableRoleId).orElseThrow(() -> new AbstractoRunTimeException("Assignable role not found"));
|
||||
@@ -60,7 +62,14 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
|
||||
|
||||
@Override
|
||||
public void deleteAssignableRole(AssignableRole assignableRole) {
|
||||
assignableRole.getAssignablePlace().getAssignableRoles().remove(assignableRole);
|
||||
assignableRole.setAssignablePlace(null);
|
||||
repository.delete(assignableRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AssignableRole> getAssignableRolesFromAssignableUserWithPlaceType(AssignedRoleUser user, AssignableRolePlaceType type) {
|
||||
return repository.findByAssignedUsersContainingAndAssignablePlace_Type(user, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.assignableroles.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlaceNotFoundException;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.repository.AssignableRolePlaceRepository;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
@@ -20,12 +21,18 @@ public class AssignableRolePlaceManagementServiceBean implements AssignableRoleP
|
||||
private AssignableRolePlaceRepository repository;
|
||||
|
||||
@Override
|
||||
public AssignableRolePlace createPlace(String name, AChannel channel, String text) {
|
||||
public AssignableRolePlace createPlace(String name, AChannel channel, String text, AssignableRolePlaceType type) {
|
||||
boolean unique = false;
|
||||
if(type.equals(AssignableRolePlaceType.BOOSTER)) {
|
||||
unique = true;
|
||||
}
|
||||
AssignableRolePlace place = AssignableRolePlace
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.server(channel.getServer())
|
||||
.text(text)
|
||||
.uniqueRoles(unique)
|
||||
.type(type)
|
||||
.key(name)
|
||||
.build();
|
||||
log.info("Creating assignable role place in channel {} on server {}.", channel.getId(), channel.getServer().getId());
|
||||
|
||||
@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@@ -43,6 +44,18 @@ public class AssignedRoleUserManagementServiceBean implements AssignedRoleUserMa
|
||||
removeAssignedRoleFromUser(assignableRole, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssignedRoleFromUsers(AssignableRole assignableRole, List<AssignedRoleUser> users) {
|
||||
log.info("Clearing all assignable role {} for {} users.", assignableRole.getId(), users.size());
|
||||
assignableRole.getAssignedUsers().removeAll(users);
|
||||
users.forEach(roleUser -> roleUser.getRoles().remove(assignableRole));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssignedRoleFromUsers(AssignableRole assignableRole) {
|
||||
removeAssignedRoleFromUsers(assignableRole, assignableRole.getAssignedUsers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssignedRoleFromUser(AssignableRole assignableRole, AssignedRoleUser user) {
|
||||
assignableRole.getAssignedUsers().remove(user);
|
||||
|
||||
@@ -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="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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="assignable_role_place-add_type">
|
||||
<addColumn tableName="assignable_role_place">
|
||||
<column name="type" type="VARCHAR2(128)" defaultValue="DEFAULT"/>
|
||||
</addColumn>
|
||||
</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="assignable_role_place.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -7,4 +7,5 @@
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="1.0-assignableRoles/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.3.4/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.assignableroles.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class BoosterAssignableRolePlaceMemberNotBoostingException extends AbstractoTemplatableException {
|
||||
|
||||
public BoosterAssignableRolePlaceMemberNotBoostingException() {
|
||||
super("Clicking member does not boost");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "assignable_role_booster_place_member_not_boosting_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -85,4 +85,8 @@ public class AssignableRolePlace implements Serializable {
|
||||
@Column(name = "updated", insertable = false, updatable = false)
|
||||
private Instant updated;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "type")
|
||||
private AssignableRolePlaceType type;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.assignableroles.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum AssignableRolePlaceType implements CommandParameterKey {
|
||||
DEFAULT, BOOSTER
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.assignableroles.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.core.models.template.display.ChannelDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -19,6 +20,7 @@ public class AssignableRolePlaceConfig {
|
||||
private String placeText;
|
||||
private ChannelDisplay channelDisplay;
|
||||
private Boolean uniqueRoles;
|
||||
private AssignableRolePlaceType type;
|
||||
/**
|
||||
* The {@link AssignableRolePlaceConfig roles} which are contained in this {@link AssignableRolePlace}
|
||||
*/
|
||||
|
||||
@@ -2,17 +2,21 @@ package dev.sheldan.abstracto.assignableroles.service;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview;
|
||||
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig;
|
||||
import dev.sheldan.abstracto.core.models.FullEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface AssignableRolePlaceService {
|
||||
void createAssignableRolePlace(String name, AChannel channel, String text);
|
||||
void createAssignableRolePlace(String name, AChannel channel, String text, AssignableRolePlaceType type);
|
||||
|
||||
CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote emote, String description);
|
||||
|
||||
@@ -42,7 +46,7 @@ public interface AssignableRolePlaceService {
|
||||
|
||||
void multipleAssignableRolePlace(AssignableRolePlace place);
|
||||
|
||||
CompletableFuture<Void> showAssignablePlaceConfig(AServer server, String name, TextChannel channel);
|
||||
AssignableRolePlaceConfig getAssignableRolePlaceConfig(Guild guild, String name);
|
||||
|
||||
CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel);
|
||||
|
||||
@@ -52,5 +56,5 @@ public interface AssignableRolePlaceService {
|
||||
|
||||
CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, String newValue);
|
||||
|
||||
CompletableFuture<Void> showAllAssignableRolePlaces(AServer server, TextChannel channel);
|
||||
AssignablePlaceOverview getAssignableRolePlaceOverview(Guild guild);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package dev.sheldan.abstracto.assignableroles.service;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
@@ -22,6 +24,8 @@ public interface AssignableRoleService {
|
||||
*/
|
||||
|
||||
CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, Member member);
|
||||
CompletableFuture<Void> assignAssignableRoleToUser(Role role, Member member);
|
||||
void assignableRoleConditionFailure();
|
||||
|
||||
/**
|
||||
* Clears all {@link AssignableRole assignableRoles} which are currently given to the {@link AUserInAServer user} of a certain
|
||||
@@ -39,6 +43,7 @@ public interface AssignableRoleService {
|
||||
* has been removed from the {@link Member member}
|
||||
*/
|
||||
CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, Member member);
|
||||
CompletableFuture<Void> removeAssignableRoleFromUser(Role role, Member member);
|
||||
|
||||
/**
|
||||
* Removes the {@link AssignableRole role} from the given {@link Member member}
|
||||
@@ -67,4 +72,6 @@ public interface AssignableRoleService {
|
||||
AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, ARole role);
|
||||
AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Long roleId);
|
||||
|
||||
void removeAssignableRolesFromAssignableRoleUser(List<AssignableRole> roles, AssignedRoleUser roleUser);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,14 +2,19 @@ package dev.sheldan.abstracto.assignableroles.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.core.models.FullEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AssignableRoleManagementService {
|
||||
AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload);
|
||||
|
||||
AssignableRole getByAssignableRoleId(Long assignableRoleId);
|
||||
void deleteAssignableRole(AssignableRole assignableRole);
|
||||
List<AssignableRole> getAssignableRolesFromAssignableUserWithPlaceType(AssignedRoleUser user, AssignableRolePlaceType type);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.assignableroles.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
|
||||
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
|
||||
@@ -9,7 +10,7 @@ import java.util.Optional;
|
||||
|
||||
public interface AssignableRolePlaceManagementService {
|
||||
|
||||
AssignableRolePlace createPlace(String name, AChannel channel, String text);
|
||||
AssignableRolePlace createPlace(String name, AChannel channel, String text, AssignableRolePlaceType type);
|
||||
|
||||
boolean doesPlaceExist(AServer server, String name);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@@ -25,6 +26,8 @@ public interface AssignedRoleUserManagementService {
|
||||
* @param aUserInAServer The {@link AUserInAServer user} from whom the {@link AssignableRole role} should be removed
|
||||
*/
|
||||
void removeAssignedRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer);
|
||||
void removeAssignedRoleFromUsers(AssignableRole assignableRole, List<AssignedRoleUser> users);
|
||||
void removeAssignedRoleFromUsers(AssignableRole assignableRole);
|
||||
|
||||
/**
|
||||
* Removes the given {@link AssignableRole assignableFrom} from the given {@link AssignedRoleUser user}.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActivityServiceBean implements ActivityService {
|
||||
List<CustomActivity> activities = activityManagementService.getAllActivities();
|
||||
if(!activities.isEmpty()) {
|
||||
CustomActivity chosen = activities.get(secureRandom.nextInt(activities.size()));
|
||||
log.info("Chosen {} activity.", chosen.getId());
|
||||
log.info("Chosen activity {}.", chosen.getId());
|
||||
switchToActivity(chosen);
|
||||
} else {
|
||||
log.info("No activities configured.");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -46,7 +46,9 @@ public class HasLevelCondition implements SystemCondition {
|
||||
log.info("Evaluating has level condition for user {} in server {} with level {}.",
|
||||
userInServer.getUserReference().getId(), userInServer.getServerReference().getId(), level);
|
||||
AUserExperience user = userExperienceManagementService.findUserInServer(userInServer);
|
||||
return user.getCurrentLevel() != null && user.getCurrentLevel().getLevel() >= level;
|
||||
boolean conditionResult = user.getCurrentLevel() != null && user.getCurrentLevel().getLevel() >= level;
|
||||
log.info("Condition evaluated to {}", conditionResult);
|
||||
return conditionResult;
|
||||
}
|
||||
log.info("No user in server object was found. Evaluating to false.");
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -168,18 +168,39 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
.stream()
|
||||
.map(EmbeddedMessage::getEmbeddingMessageId)
|
||||
.collect(Collectors.toList());
|
||||
List<String> componentPayloadsToDelete = embeddedMessages
|
||||
.stream()
|
||||
.map(EmbeddedMessage::getDeletionComponentId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
List<CompletableFuture<Message>> reactionMessageFutures = messageService.retrieveMessages(reactionChannelMessages);
|
||||
List<CompletableFuture<Message>> buttonMessageFutures = messageService.retrieveMessages(buttonChannelMessages);
|
||||
CompletableFutureList<Message> reactionFutureList = new CompletableFutureList<>(reactionMessageFutures);
|
||||
CompletableFutureList<Message> buttonFutureList = new CompletableFutureList<>(buttonMessageFutures);
|
||||
return reactionFutureList.getMainFuture()
|
||||
.handle((unused, throwable) -> self.removeReactions(reactionFutureList.getObjects()))
|
||||
.handle((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Embedded messages reaction message loading failed.", throwable);
|
||||
}
|
||||
return self.removeReactions(reactionFutureList.getObjects());
|
||||
})
|
||||
.thenCompose(Function.identity())
|
||||
.thenCompose(unused -> buttonFutureList.getMainFuture())
|
||||
.handle((unused, throwable) -> self.removeButtons(buttonFutureList.getObjects()))
|
||||
.handle((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Embedded messages button message loading failed.", throwable);
|
||||
}
|
||||
return self.removeButtons(buttonFutureList.getObjects());
|
||||
})
|
||||
// deleting the messages from db regardless of exceptions, at most the reaction remains
|
||||
.thenCompose(Function.identity())
|
||||
.whenComplete((unused, throwable) -> self.deleteEmbeddedMessages(embeddedMessagesHandled))
|
||||
.whenComplete((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Embedded message button clearing failed.", throwable);
|
||||
}
|
||||
self.deleteEmbeddedMessages(embeddedMessagesHandled, componentPayloadsToDelete);
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to clean up embedded messages.", throwable);
|
||||
return null;
|
||||
@@ -216,8 +237,9 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteEmbeddedMessages(List<Long> embeddedMessagesToDelete) {
|
||||
public void deleteEmbeddedMessages(List<Long> embeddedMessagesToDelete, List<String> componentPayloadsToDelete) {
|
||||
messageEmbedPostManagementService.deleteEmbeddedMessagesViaId(embeddedMessagesToDelete);
|
||||
componentPayloadManagementService.deletePayloads(componentPayloadsToDelete);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
|
||||
import dev.sheldan.abstracto.core.utils.ContextUtils;
|
||||
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.logging.config.LoggingFeatureDefinition;
|
||||
import dev.sheldan.abstracto.logging.config.LoggingPostTarget;
|
||||
import dev.sheldan.abstracto.logging.model.template.MessageDeletedAttachmentLog;
|
||||
@@ -81,11 +82,14 @@ public class MessageDeleteLogListener implements AsyncMessageDeletedListener {
|
||||
.member(authorMember)
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel, messageFromCache.getServerId());
|
||||
postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId())).exceptionally(throwable -> {
|
||||
log.error("Failed to send message deleted log.", throwable);
|
||||
return null;
|
||||
});
|
||||
if(messageFromCache.getAttachments() != null){
|
||||
log.debug("Notifying about deletions of {} attachments.", messageFromCache.getAttachments().size());
|
||||
for (int i = 0; i < messageFromCache.getAttachments().size(); i++) {
|
||||
MessageDeletedAttachmentLog log = MessageDeletedAttachmentLog
|
||||
MessageDeletedAttachmentLog attachmentLogModel = MessageDeletedAttachmentLog
|
||||
.builder()
|
||||
.imageUrl(messageFromCache.getAttachments().get(i).getProxyUrl())
|
||||
.counter(i + 1)
|
||||
@@ -93,8 +97,12 @@ public class MessageDeleteLogListener implements AsyncMessageDeletedListener {
|
||||
.channel(textChannel)
|
||||
.member(authorMember)
|
||||
.build();
|
||||
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, log, messageFromCache.getServerId());
|
||||
postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId());
|
||||
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, attachmentLogModel, messageFromCache.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send message deleted log.", throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ public class Ban extends AbstractConditionableCommand {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
User user = (User) parameters.get(0);
|
||||
String defaultReason = templateService.renderSimpleTemplate(BAN_DEFAULT_REASON_TEMPLATE, commandContext.getGuild().getIdLong());
|
||||
String reason = parameters.size() == 2 ? (String) parameters.get(1) : defaultReason;
|
||||
String reason = (String) parameters.get(1);
|
||||
|
||||
return banService.banUser(user, reason, commandContext.getAuthor(), commandContext.getMessage())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
@@ -51,7 +50,7 @@ public class Ban extends AbstractConditionableCommand {
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("user").templated(true).type(User.class).build());
|
||||
parameters.add(Parameter.builder().name("reason").templated(true).type(String.class).optional(true).remainder(true).build());
|
||||
parameters.add(Parameter.builder().name("reason").templated(true).type(String.class).remainder(true).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
List<EffectConfig> effectConfig = Arrays.asList(EffectConfig.builder().position(0).effectKey(BAN_EFFECT_KEY).build());
|
||||
return CommandConfiguration.builder()
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.sheldan.abstracto.moderation.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.EffectConfig;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.abstracto.moderation.service.BanService.BAN_EFFECT_KEY;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SoftBan extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private BanService banService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
User user = (User) parameters.get(0);
|
||||
Duration delDays = Duration.ofDays(7);
|
||||
if(parameters.size() > 1) {
|
||||
delDays = (Duration) parameters.get(1);
|
||||
}
|
||||
return banService.softBanUser(commandContext.getGuild(), user, delDays)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("user").templated(true).type(User.class).build());
|
||||
parameters.add(Parameter.builder().name("delDays").templated(true).type(Duration.class).optional(true).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
List<EffectConfig> effectConfig = Arrays.asList(EffectConfig.builder().position(0).effectKey(BAN_EFFECT_KEY).build());
|
||||
return CommandConfiguration.builder()
|
||||
.name("softBan")
|
||||
.module(ModerationModuleDefinition.MODERATION)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.effects(effectConfig)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MODERATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandCondition> getConditions() {
|
||||
List<CommandCondition> conditions = super.getConditions();
|
||||
conditions.add(immuneUserCondition);
|
||||
return conditions;
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ public class UserBannedListener implements AsyncUserBannedListener {
|
||||
.queue(auditLogEntries -> {
|
||||
if(auditLogEntries.isEmpty()) {
|
||||
log.info("Did not find recent bans in guild {}.", model.getServerId());
|
||||
self.sendBannedNotification(model.getUser(), null, null, model.getServerId());
|
||||
return;
|
||||
}
|
||||
Optional<AuditLogEntry> banEntryOptional = auditLogEntries
|
||||
@@ -65,6 +66,9 @@ public class UserBannedListener implements AsyncUserBannedListener {
|
||||
log.info("Did not find the banned user in the most recent bans for guild {}. Not adding audit log information.", model.getServerId());
|
||||
self.sendBannedNotification(model.getUser(), null, null, model.getServerId());
|
||||
}
|
||||
}, throwable -> {
|
||||
log.error("Retrieving bans for guild {} failed - logging ban regardless.", model.getServerId());
|
||||
self.sendBannedNotification(model.getUser(), null, null, model.getServerId());
|
||||
});
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.dv8tion.jda.api.entities.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -58,7 +59,7 @@ public class BanServiceBean implements BanService {
|
||||
.commandMessage(message)
|
||||
.reason(reason)
|
||||
.build();
|
||||
CompletableFuture<Void> banFuture = banUser(member.getGuild(), member.getUser(), reason);
|
||||
CompletableFuture<Void> banFuture = banUser(member.getGuild(), member.getUser(), 0, reason);
|
||||
CompletableFuture<Void> messageFuture = sendBanLogMessage(banLog, member.getGuild().getIdLong(), BAN_LOG_TEMPLATE);
|
||||
return CompletableFuture.allOf(banFuture, messageFuture);
|
||||
}
|
||||
@@ -81,7 +82,7 @@ public class BanServiceBean implements BanService {
|
||||
.thenAccept(message1 -> log.info("Notified about not being able to send ban notification in server {} and channel {} based on message {} from user {}."
|
||||
, message.getGuild().getIdLong(), message.getChannel().getIdLong(), message.getIdLong(), message.getAuthor().getIdLong()));
|
||||
}
|
||||
CompletableFuture<Void> banFuture = banUser(guild, user, reason);
|
||||
CompletableFuture<Void> banFuture = banUser(guild, user, 0, reason);
|
||||
CompletableFuture<Void> messageFuture = sendBanLogMessage(banLog, guild.getIdLong(), BAN_LOG_TEMPLATE);
|
||||
CompletableFuture.allOf(banFuture, messageFuture)
|
||||
.thenAccept(unused1 -> returningFuture.complete(null))
|
||||
@@ -111,10 +112,29 @@ public class BanServiceBean implements BanService {
|
||||
.bannedUser(user)
|
||||
.unBanningMember(unBanningMember)
|
||||
.build();
|
||||
return unBanUser(guild, user)
|
||||
return unbanUser(guild, user)
|
||||
.thenCompose(unused -> self.sendUnBanLogMessage(banLog, guild.getIdLong(), UN_BAN_LOG_TEMPLATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> banUser(Guild guild, User user, Integer deletionDays, String reason) {
|
||||
log.info("Banning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
return guild.ban(user, deletionDays, reason).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> unbanUser(Guild guild, User user) {
|
||||
log.info("Unbanning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
return guild.unban(user).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> softBanUser(Guild guild, User user, Duration delDays) {
|
||||
Long days = delDays.toDays();
|
||||
return banUser(guild, user, days.intValue(), "")
|
||||
.thenCompose(unused -> unbanUser(guild, user));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> sendBanLogMessage(BanLog banLog, Long guildId, String template) {
|
||||
CompletableFuture<Void> completableFuture;
|
||||
MessageToSend banLogMessage = templateService.renderEmbedTemplate(template, banLog, guildId);
|
||||
@@ -132,14 +152,4 @@ public class BanServiceBean implements BanService {
|
||||
completableFuture = FutureUtils.toSingleFutureGeneric(notificationFutures);
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> banUser(Guild guild, User user, String reason) {
|
||||
log.info("Banning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
return guild.ban(user, 0, reason).submit();
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> unBanUser(Guild guild, User user) {
|
||||
log.info("Unbanning user {} in guild {}.", user.getIdLong(), guild.getId());
|
||||
return guild.unban(user).submit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,4 +378,10 @@ public class MuteServiceBean implements MuteService {
|
||||
completelyUnMuteUser(userInServerManagementService.loadOrCreateUser(member));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> muteMemberWithoutContext(Member member) {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
return applyMuteRole(aUserInAServer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,20 @@
|
||||
<?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="moderationFeature" value="(SELECT id FROM feature WHERE key = 'moderation')"/>
|
||||
|
||||
<changeSet author="Sheldan" id="softBan-command">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="softBan"/>
|
||||
<column name="module_id" valueComputed="${moderationModule}"/>
|
||||
<column name="feature_id" valueComputed="${moderationFeature}"/>
|
||||
</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="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -10,4 +10,5 @@
|
||||
<include file="1.2.11-moderation/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.15/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.16/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.3.4/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -31,36 +31,16 @@ public class BanTest {
|
||||
@Mock
|
||||
private BanService banService;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Member> banLogModelCaptor;
|
||||
|
||||
private static final String REASON = "reason";
|
||||
private static final Long SERVER_ID = 1L;
|
||||
|
||||
@Mock
|
||||
private User bannedMember;
|
||||
|
||||
@Test
|
||||
public void testBanWithDefaultReason() {
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(bannedMember));
|
||||
when(parameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
|
||||
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE, SERVER_ID)).thenReturn(REASON);
|
||||
when(banService.banUser(eq(bannedMember), eq(REASON), banLogModelCaptor.capture(), any(Message.class))).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
Member banningMember = banLogModelCaptor.getValue();
|
||||
Assert.assertEquals(parameters.getAuthor(), banningMember);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBanWithReason() {
|
||||
String customReason = "reason2";
|
||||
CommandContext parameters = CommandTestUtilities.getWithParameters(Arrays.asList(bannedMember, customReason));
|
||||
when(parameters.getGuild().getIdLong()).thenReturn(SERVER_ID);
|
||||
when(templateService.renderSimpleTemplate(Ban.BAN_DEFAULT_REASON_TEMPLATE, SERVER_ID)).thenReturn(REASON);
|
||||
when(banService.banUser(eq(bannedMember), eq(customReason), banLogModelCaptor.capture(), any(Message.class))).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(parameters);
|
||||
Member banningMember = banLogModelCaptor.getValue();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package dev.sheldan.abstracto.moderation.service;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface BanService {
|
||||
@@ -11,4 +13,7 @@ public interface BanService {
|
||||
CompletableFuture<Void> banMember(Member member, String reason, Member banningMember, Message message);
|
||||
CompletableFuture<Void> banUser(User user, String reason, Member banningMember, Message message);
|
||||
CompletableFuture<Void> unBanUser(User user, Member unBanningUser);
|
||||
CompletableFuture<Void> banUser(Guild guild, User user, Integer deletionDays, String reason);
|
||||
CompletableFuture<Void> unbanUser(Guild guild, User user);
|
||||
CompletableFuture<Void> softBanUser(Guild guild, User user, Duration delDays);
|
||||
}
|
||||
|
||||
@@ -23,4 +23,5 @@ public interface MuteService {
|
||||
CompletableFuture<Void> endMute(Long muteId, Long serverId);
|
||||
void completelyUnMuteUser(AUserInAServer aUserInAServer);
|
||||
void completelyUnMuteMember(Member member);
|
||||
CompletableFuture<Void> muteMemberWithoutContext(Member member);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -62,6 +63,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* The config key to use for the ID of the category to create {@link MessageChannel} in
|
||||
*/
|
||||
public static final String MODMAIL_CATEGORY = "modmailCategory";
|
||||
public static final String TEXT_CHANNEL_NAME_TEMPLATE_KEY = "modMail_channel_name";
|
||||
/**
|
||||
* The template key used for default mod mail exceptions
|
||||
*/
|
||||
@@ -189,7 +191,16 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
metricService.incrementCounter(MODMAIL_THREAD_CREATED_COUNTER);
|
||||
User user = member.getUser();
|
||||
log.info("Creating modmail channel for user {} in category {} on server {}.", user.getId(), categoryId, serverId);
|
||||
CompletableFuture<TextChannel> textChannelFuture = channelService.createTextChannel(user.getName() + user.getDiscriminator(), server, categoryId);
|
||||
ModMailChannelNameModel model = ModMailChannelNameModel
|
||||
.builder()
|
||||
.serverId(serverId)
|
||||
.userId(member.getIdLong())
|
||||
.randomText(RandomStringUtils.randomAlphanumeric(25))
|
||||
.uuid(UUID.randomUUID().toString())
|
||||
.currentDate(Instant.now())
|
||||
.build();
|
||||
String channelName = templateService.renderTemplate(TEXT_CHANNEL_NAME_TEMPLATE_KEY, model, serverId);
|
||||
CompletableFuture<TextChannel> textChannelFuture = channelService.createTextChannel(channelName, server, categoryId);
|
||||
return textChannelFuture.thenCompose(channel -> {
|
||||
undoActions.add(UndoActionInstance.getChannelDeleteAction(serverId, channel.getIdLong()));
|
||||
return self.performModMailThreadSetup(member, initialMessage, channel, userInitiated, undoActions, feedBackChannel);
|
||||
@@ -361,7 +372,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
future.completeExceptionally(exception);
|
||||
return future;
|
||||
}
|
||||
}).exceptionally(throwable -> {
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to load member {} for modmail in server {}.", userId, chosenServerId, throwable);
|
||||
return null;
|
||||
});
|
||||
@@ -537,7 +548,6 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
@Transactional
|
||||
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message replyCommandMessage, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions, Member targetMember) {
|
||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", replyCommandMessage.getId(), targetMember.getId(), modmailThreadId, targetMember.getGuild().getId());
|
||||
AUserInAServer moderator = userInServerManagementService.loadOrCreateUser(replyCommandMessage.getMember());
|
||||
metricService.incrementCounter(MDOMAIL_THREAD_MESSAGE_SENT);
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
||||
FullUserInServer fullThreadUser = FullUserInServer
|
||||
@@ -556,9 +566,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
log.debug("Message is sent anonymous.");
|
||||
modMailModeratorReplyModelBuilder.moderator(memberService.getBotInGuild(modMailThread.getServer()));
|
||||
} else {
|
||||
// should be loaded, because we are currently processing a command caused by the message
|
||||
Member moderatorMember = memberService.getMemberInServer(moderator);
|
||||
modMailModeratorReplyModelBuilder.moderator(moderatorMember);
|
||||
modMailModeratorReplyModelBuilder.moderator(replyCommandMessage.getMember());
|
||||
}
|
||||
ModMailModeratorReplyModel modMailUserReplyModel = modMailModeratorReplyModelBuilder.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY, modMailUserReplyModel, modMailThread.getServer().getId());
|
||||
@@ -570,7 +578,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
sameThreadMessageFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, moderator, future.join(), replyCommandMessage, sameThreadMessageFuture.join())
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, future.join(), replyCommandMessage, sameThreadMessageFuture.join())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -752,11 +760,11 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.build();
|
||||
List<CompletableFuture<Message>> updateMessageFutures = channelService.sendEmbedTemplateInTextChannelList(MODMAIL_CLOSE_PROGRESS_TEMPLATE_KEY, progressModel, channel);
|
||||
return FutureUtils.toSingleFutureGeneric(updateMessageFutures)
|
||||
.thenApply(updateMessage -> self.logMessages(modMailThreadId, messages, context, updateMessageFutures.get(0).join()));
|
||||
.thenCompose(updateMessage -> self.logMessages(modMailThreadId, messages, context, updateMessageFutures.get(0).join()));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFutureList<Message> logMessages(Long modMailThreadId, ModmailLoggingThreadMessages messages, ClosingContext context, Message updateMessage) {
|
||||
public CompletableFuture<CompletableFutureList<Message>> logMessages(Long modMailThreadId, ModmailLoggingThreadMessages messages, ClosingContext context, Message updateMessage) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
@@ -789,10 +797,11 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
List<CompletableFuture<Message>> completableFutures = new ArrayList<>();
|
||||
log.debug("Sending close header and individual mod mail messages to mod mail log target for thread {}.", modMailThreadId);
|
||||
CompletableFuture<Message> headerFuture = loadUserAndSendClosingHeader(modMailThread, context);
|
||||
// TODO the header might end up later on discord servers, this look out of order
|
||||
completableFutures.add(headerFuture);
|
||||
completableFutures.addAll(self.sendMessagesToPostTarget(modMailThread, loggedMessages, updateMessage));
|
||||
return new CompletableFutureList<>(completableFutures);
|
||||
return headerFuture.thenApply(message -> {
|
||||
completableFutures.addAll(self.sendMessagesToPostTarget(modMailThreadId, loggedMessages, updateMessage));
|
||||
return new CompletableFutureList<>(completableFutures);
|
||||
});
|
||||
} else {
|
||||
throw new ModMailThreadNotFoundException(modMailThreadId);
|
||||
}
|
||||
@@ -803,11 +812,10 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.builder()
|
||||
.closingMember(closingContext.getClosingMember())
|
||||
.note(closingContext.getNote())
|
||||
.silently(closingContext.getNotifyUser())
|
||||
.silently(!closingContext.getNotifyUser())
|
||||
.messageCount(modMailThread.getMessages().size())
|
||||
.startDate(modMailThread.getCreated())
|
||||
.serverId(modMailThread.getServer().getId())
|
||||
.silently(!closingContext.getNotifyUser())
|
||||
.userId(modMailThread.getUser().getUserReference().getId())
|
||||
.build();
|
||||
return userService.retrieveUserForId(modMailThread.getUser().getUserReference().getId()).thenApply(user -> {
|
||||
@@ -843,11 +851,11 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
/**
|
||||
* Renders the retrieved {@link Message} which are in {@link ModMailLoggedMessageModel} into {@link MessageToSend} and
|
||||
* sends this to the appropriate logging {@link PostTarget}
|
||||
* @param modMailThread The {@link ModMailThread} to which the loaded messages belong to
|
||||
* @param modMailThreadId The ID of {@link ModMailThread} to which the loaded messages belong to
|
||||
* @param loadedMessages The list of {@link ModMailLoggedMessageModel} which can be rendered
|
||||
* @return A list of {@link CompletableFuture} which represent each of the messages being send to the {@link PostTarget}
|
||||
*/
|
||||
public List<CompletableFuture<Message>> sendMessagesToPostTarget(ModMailThread modMailThread, List<ModMailLoggedMessageModel> loadedMessages, Message updateMessage) {
|
||||
public List<CompletableFuture<Message>> sendMessagesToPostTarget(Long modMailThreadId, List<ModMailLoggedMessageModel> loadedMessages, Message updateMessage) {
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
ClosingProgressModel progressModel = ClosingProgressModel
|
||||
.builder()
|
||||
@@ -857,9 +865,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
loadedMessages = loadedMessages.stream().sorted(Comparator.comparing(o -> o.getMessage().getTimeCreated())).collect(Collectors.toList());
|
||||
for (int i = 0; i < loadedMessages.size(); i++) {
|
||||
ModMailLoggedMessageModel message = loadedMessages.get(i);
|
||||
log.debug("Sending message {} of modmail thread {} to modmail log post target.", modMailThread.getId(), message.getMessage().getId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_close_logged_message", message, modMailThread.getServer().getId());
|
||||
List<CompletableFuture<Message>> logFuture = postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_LOG, modMailThread.getServer().getId());
|
||||
log.debug("Sending message {} of modmail thread {} to modmail log post target.", modMailThreadId, message.getMessage().getId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("modmail_close_logged_message", message, updateMessage.getGuild().getIdLong());
|
||||
List<CompletableFuture<Message>> logFuture = postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_LOG, updateMessage.getGuild().getIdLong());
|
||||
if(i != 0 && (i % 10) == 0) {
|
||||
progressModel.setLoggedMessages(i);
|
||||
messageService.editMessageWithNewTemplate(updateMessage, MODMAIL_CLOSE_PROGRESS_TEMPLATE_KEY, progressModel);
|
||||
@@ -874,15 +882,15 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* and updates the state of the {@link ModMailThread}.
|
||||
* @param modMailThreadId The ID of the {@link ModMailThread} for which the messages were sent for
|
||||
* @param anonymous Whether or not the messages were send anonymous
|
||||
* @param moderator The original {@link AUserInAServer} which authored the messages
|
||||
* @param createdMessageInDM The {@link Message message} which was sent to the private channel with the {@link User user}
|
||||
* @param modMailThreadMessage The {@link Message message} which was sent in the channel representing the {@link ModMailThread thread}. Might be null.
|
||||
* @param replyCommandMessage The {@link Message message} which contained the command used to reply to the user
|
||||
* @throws ModMailThreadNotFoundException in case the {@link ModMailThread} is not found by the ID
|
||||
*/
|
||||
@Transactional
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, AUserInAServer moderator, Message createdMessageInDM, Message replyCommandMessage, Message modMailThreadMessage) {
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, Message createdMessageInDM, Message replyCommandMessage, Message modMailThreadMessage) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
AUserInAServer moderator = userInServerManagementService.loadOrCreateUser(replyCommandMessage.getMember());
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.debug("Adding (anonymous: {}) message {} of moderator to modmail thread {} and setting state to {}.", anonymous, createdMessageInDM.getId(), modMailThreadId, ModMailThreadState.MOD_REPLIED);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.abstracto.modmail.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class ModMailChannelNameModel {
|
||||
private Long serverId;
|
||||
private Long userId;
|
||||
private Instant currentDate;
|
||||
private String randomText;
|
||||
private String uuid;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<module>profanity-filter</module>
|
||||
<module>voice-channel-context</module>
|
||||
<module>dynamic-activity</module>
|
||||
<module>anti-raid</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.3.2</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user