mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-30 07:06:24 +00:00
Compare commits
51 Commits
release-20
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f12ac7107 | ||
|
|
81b1688d97 | ||
|
|
3500ec4123 | ||
|
|
4495b12e84 | ||
|
|
1f1cb0ed34 | ||
|
|
a778518475 | ||
|
|
fa62353aee | ||
|
|
2f125d0101 | ||
|
|
4dc92fe49b | ||
|
|
5e908f6837 | ||
|
|
95a2813c34 | ||
|
|
d844e09f4d | ||
|
|
8251074aab | ||
|
|
4180a07243 | ||
|
|
cf9e5f67f6 | ||
|
|
ae53784da2 | ||
|
|
342f0b6043 | ||
|
|
274dd77eeb | ||
|
|
0f6adacd90 | ||
|
|
2dd5841397 | ||
|
|
a2f49a0de9 | ||
|
|
c791c063e3 | ||
|
|
d293d764db | ||
|
|
a7cd674cdd | ||
|
|
0abefe64e9 | ||
|
|
d1267605c1 | ||
|
|
b4ffea341c | ||
|
|
507c755809 | ||
|
|
9e0e92a530 | ||
|
|
d078b3fa87 | ||
|
|
71b7dd2383 | ||
|
|
ea0384490e | ||
|
|
b5dbc0b1ed | ||
|
|
e265eb6760 | ||
|
|
2f18b7431d | ||
|
|
2d8827fa81 | ||
|
|
dddeb15127 | ||
|
|
78fbe0723b | ||
|
|
e1d4a41d60 | ||
|
|
354a82f806 | ||
|
|
ff3e3d85ba | ||
|
|
46bf4fbc42 | ||
|
|
97ac25dbb6 | ||
|
|
ef4bdb2ab2 | ||
|
|
433fdb7068 | ||
|
|
e59b6269e1 | ||
|
|
8077501584 | ||
|
|
cb9ab8f542 | ||
|
|
f513f8890b | ||
|
|
6f02834b75 | ||
|
|
75456b45c9 |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
||||
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
||||
VERSION=1.6.9
|
||||
VERSION=1.6.20
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -108,6 +108,6 @@ public class MassPingServiceBean implements MassPingService {
|
||||
.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()));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, AntiRaidPostTarget.MASS_PING_LOG, member.getGuild().getIdLong()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public class CreateAssignableRolePlace extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
|
||||
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT.intValue()));
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
|
||||
@@ -95,7 +95,7 @@ public class CreateAssignableRolePlace extends AbstractConditionableCommand {
|
||||
.templated(true)
|
||||
.optional(true)
|
||||
.build();
|
||||
List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
|
||||
List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT.intValue()));
|
||||
Parameter text = Parameter
|
||||
.builder()
|
||||
.name(ASSIGNABLE_ROLE_PLACE_TEXT_PARAMETER)
|
||||
|
||||
@@ -31,7 +31,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
|
||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||
import net.dv8tion.jda.api.components.buttons.ButtonStyle;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -60,9 +59,6 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private GuildService guildService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@@ -131,9 +127,18 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
String buttonId = componentService.generateComponentId();
|
||||
String emoteMarkdown = emoji != null ? emoji.getFormatted() : null;
|
||||
if (assignableRolePlace.getMessageId() != null) {
|
||||
AssignablePostMessage model = prepareAssignablePostMessageModel(assignableRolePlace);
|
||||
model.getRoles().add(AssignablePostRole
|
||||
.builder()
|
||||
.componentId(buttonId)
|
||||
.emoteMarkDown(emoteMarkdown)
|
||||
.description(description)
|
||||
.build());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ASSIGNABLE_ROLES_POST_TEMPLATE_KEY, model, assignableRolePlace.getServer().getId());
|
||||
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, emoji, buttonId));
|
||||
return messageService.editMessageInChannel(textChannel, messageToSend, assignableRolePlace.getMessageId()).thenAccept(unused -> {
|
||||
self.persistAssignableRoleAddition(placeId, role, description, emoji, buttonId);
|
||||
});
|
||||
} else {
|
||||
log.info("Assignable role place {} is not yet setup - only adding role to the database.", assignableRolePlace.getId());
|
||||
self.persistAssignableRoleAddition(placeId, role, description, emoji, buttonId);
|
||||
@@ -174,7 +179,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
return channelService.retrieveMessageInChannel(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId())
|
||||
.thenCompose(message -> {
|
||||
log.debug("Updating message {} to remove component with ID {}.", message.getIdLong(), componentId);
|
||||
return componentService.removeComponentWithId(message, componentId, true);
|
||||
return componentService.removeComponentById(message, componentId).thenAccept(message1 -> {});
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -269,8 +274,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
log.info("Deactivating assignable role place {} in server {}", place.getId(), place.getServer().getId());
|
||||
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
|
||||
.thenCompose(message ->
|
||||
componentService.disableAllButtons(message)
|
||||
);
|
||||
componentService.disableAllComponents(message)
|
||||
).thenAccept(message -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,8 +288,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
|
||||
log.info("Activating assignable role place {} in server {}", place.getId(), place.getServer().getId());
|
||||
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
|
||||
.thenCompose(message ->
|
||||
componentService.enableAllButtons(message)
|
||||
);
|
||||
componentService.enableAllComponents(message)
|
||||
).thenAccept(message -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ public class TransferCredits extends AbstractConditionableCommand {
|
||||
.name(MEMBER_PARAMETER)
|
||||
.templated(true)
|
||||
.type(Member.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
Parameter amountParameter = Parameter
|
||||
@@ -82,7 +81,6 @@ public class TransferCredits extends AbstractConditionableCommand {
|
||||
.name(AMOUNT_PARAMETER)
|
||||
.templated(true)
|
||||
.type(Integer.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(memberParameter, amountParameter);
|
||||
|
||||
@@ -200,8 +200,8 @@ public class EntertainmentServiceBean implements EntertainmentService {
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageEmbedToSendToAChannel(messageToSend, pressF.getPressFChannel()))
|
||||
.thenCompose(unused -> messageService.loadMessage(serverId, channelId, messageId).thenCompose(message -> {
|
||||
log.info("Clearing buttons from pressF {} in with message {} in channel {} in server {}.", pressFId, pressFId, channelId, serverId);
|
||||
return componentService.clearButtons(message);
|
||||
}));
|
||||
return componentService.clearComponents(message);
|
||||
})).thenAccept(message -> {});
|
||||
} else {
|
||||
throw new AbstractoRunTimeException(String.format("PressF with id %s not found.", pressFId));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
} else {
|
||||
leaderBoard = userExperienceService.findLeaderBoardData(server, page);
|
||||
}
|
||||
List<CompletableFuture> futures = new ArrayList<>();
|
||||
List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard, actorUser.getGuild().getIdLong());
|
||||
futures.add(completableFutures);
|
||||
log.info("Rendering leaderboard for page {} in server {} for user {}.", page, actorUser.getId(), actorUser.getGuild().getId());
|
||||
@@ -158,7 +158,6 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
Parameter focusMe = Parameter
|
||||
.builder()
|
||||
.name(FOCUS_PARAMETER)
|
||||
.validators(leaderBoardPageValidators)
|
||||
.optional(true)
|
||||
.slashCommandOnly(true)
|
||||
.templated(true)
|
||||
|
||||
@@ -313,107 +313,107 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
Long userInServerId = userInAServer.getUserInServerId();
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
|
||||
AUserExperience aUserExperience = aUserExperienceOptional.orElseGet(() -> userExperienceManagementService.createUserInServer(userInAServer));
|
||||
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
|
||||
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
|
||||
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
|
||||
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
|
||||
Long experienceRange = maxExp - minExp + 1;
|
||||
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
|
||||
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
|
||||
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
|
||||
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
|
||||
|
||||
Long oldExperience = aUserExperience.getExperience();
|
||||
Long newExperienceCount = oldExperience + gainedExperience;
|
||||
aUserExperience.setExperience(newExperienceCount);
|
||||
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
|
||||
RoleCalculationResult result = RoleCalculationResult
|
||||
.builder()
|
||||
.build();
|
||||
boolean userChangesLevel = !Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel());
|
||||
Integer oldLevel = aUserExperience.getCurrentLevel() != null ? aUserExperience.getCurrentLevel().getLevel() : 0;
|
||||
if(userChangesLevel) {
|
||||
log.info("User {} in server {} changed level. New {}, Old {}.", member.getIdLong(),
|
||||
member.getGuild().getIdLong(), newLevel.getLevel(),
|
||||
oldLevel);
|
||||
aUserExperience.setCurrentLevel(newLevel);
|
||||
AExperienceRole calculatedNewRole = experienceRoleService.calculateRole(roles, newLevel.getLevel());
|
||||
Long oldRoleId = aUserExperience.getCurrentExperienceRole() != null && aUserExperience.getCurrentExperienceRole().getRole() != null ? aUserExperience.getCurrentExperienceRole().getRole().getId() : null;
|
||||
Long newRoleId = calculatedNewRole != null && calculatedNewRole.getRole() != null ? calculatedNewRole.getRole().getId() : null;
|
||||
result.setOldRoleId(oldRoleId);
|
||||
result.setNewRoleId(newRoleId);
|
||||
if(message != null
|
||||
&& aUserExperience.getLevelUpNotification()
|
||||
&& featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, serverId, ExperienceFeatureMode.LEVEL_UP_NOTIFICATION)) {
|
||||
LevelUpNotificationModel model = LevelUpNotificationModel
|
||||
.builder()
|
||||
.memberDisplay(MemberDisplay.fromMember(member))
|
||||
.oldExperience(oldExperience)
|
||||
.newExperience(newExperienceCount)
|
||||
.newLevel(newLevel.getLevel())
|
||||
.oldLevel(oldLevel)
|
||||
.newRole(oldRoleId != null ? RoleDisplay.fromRole(oldRoleId) : null)
|
||||
.newRole(newRoleId != null ? RoleDisplay.fromRole(newRoleId) : null)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("experience_level_up_notification", model, serverId);
|
||||
FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, message.getChannel())).thenAccept(unused -> {
|
||||
log.info("Sent level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to send level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
aUserExperience.setCurrentExperienceRole(calculatedNewRole);
|
||||
}
|
||||
aUserExperience.setMessageCount(aUserExperience.getMessageCount() + 1L);
|
||||
if(userChangesLevel && featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
|
||||
levelActionService.applyLevelActionsToUser(aUserExperience, oldLevel)
|
||||
.thenAccept(unused -> {
|
||||
log.info("Executed level actions for user {}.", userInServerId);
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to execute level actions for user {}.", userInServerId, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(aUserExperienceOptional.isEmpty()) {
|
||||
userExperienceManagementService.saveUser(aUserExperience);
|
||||
}
|
||||
if(!Objects.equals(result.getOldRoleId(), result.getNewRoleId())) {
|
||||
if(result.getOldRoleId() != null && result.getNewRoleId() != null) {
|
||||
roleService.updateRolesIds(member, Arrays.asList(result.getOldRoleId()), Arrays.asList(result.getNewRoleId())).thenAccept(unused -> {
|
||||
log.debug("Removed role {} from and added role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to remove role {} from and add role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
if(result.getOldRoleId() != null) {
|
||||
roleService.removeRoleFromMemberAsync(member, result.getOldRoleId()).thenAccept(unused -> {
|
||||
log.debug("Removed role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to remove role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(result.getNewRoleId() != null) {
|
||||
roleService.addRoleToMemberAsync(member, result.getNewRoleId()).thenAccept(unused -> {
|
||||
log.debug("Added role {} to member {} in server {}.", result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to add role {} to member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (aUserExperience.getExperienceGainDisabled().equals(Boolean.TRUE)) {
|
||||
log.debug("Experience gain was disabled. User did not gain any experience.");
|
||||
return;
|
||||
}
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
|
||||
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
|
||||
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
|
||||
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
|
||||
Long experienceRange = maxExp - minExp + 1;
|
||||
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
|
||||
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
|
||||
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
|
||||
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
|
||||
|
||||
Long oldExperience = aUserExperience.getExperience();
|
||||
Long newExperienceCount = oldExperience + gainedExperience;
|
||||
aUserExperience.setExperience(newExperienceCount);
|
||||
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
|
||||
RoleCalculationResult result = RoleCalculationResult
|
||||
.builder()
|
||||
.build();
|
||||
boolean userChangesLevel = !Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel());
|
||||
Integer oldLevel = aUserExperience.getCurrentLevel() != null ? aUserExperience.getCurrentLevel().getLevel() : 0;
|
||||
if(userChangesLevel) {
|
||||
log.info("User {} in server {} changed level. New {}, Old {}.", member.getIdLong(),
|
||||
member.getGuild().getIdLong(), newLevel.getLevel(),
|
||||
oldLevel);
|
||||
aUserExperience.setCurrentLevel(newLevel);
|
||||
AExperienceRole calculatedNewRole = experienceRoleService.calculateRole(roles, newLevel.getLevel());
|
||||
Long oldRoleId = aUserExperience.getCurrentExperienceRole() != null && aUserExperience.getCurrentExperienceRole().getRole() != null ? aUserExperience.getCurrentExperienceRole().getRole().getId() : null;
|
||||
Long newRoleId = calculatedNewRole != null && calculatedNewRole.getRole() != null ? calculatedNewRole.getRole().getId() : null;
|
||||
result.setOldRoleId(oldRoleId);
|
||||
result.setNewRoleId(newRoleId);
|
||||
if(message != null
|
||||
&& aUserExperience.getLevelUpNotification()
|
||||
&& featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, serverId, ExperienceFeatureMode.LEVEL_UP_NOTIFICATION)) {
|
||||
LevelUpNotificationModel model = LevelUpNotificationModel
|
||||
.builder()
|
||||
.memberDisplay(MemberDisplay.fromMember(member))
|
||||
.oldExperience(oldExperience)
|
||||
.newExperience(newExperienceCount)
|
||||
.newLevel(newLevel.getLevel())
|
||||
.oldLevel(oldLevel)
|
||||
.newRole(oldRoleId != null ? RoleDisplay.fromRole(oldRoleId) : null)
|
||||
.newRole(newRoleId != null ? RoleDisplay.fromRole(newRoleId) : null)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("experience_level_up_notification", model, serverId);
|
||||
FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, message.getChannel())).thenAccept(unused -> {
|
||||
log.info("Sent level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to send level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
aUserExperience.setCurrentExperienceRole(calculatedNewRole);
|
||||
}
|
||||
aUserExperience.setMessageCount(aUserExperience.getMessageCount() + 1L);
|
||||
if(userChangesLevel && featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
|
||||
levelActionService.applyLevelActionsToUser(aUserExperience, oldLevel)
|
||||
.thenAccept(unused -> {
|
||||
log.info("Executed level actions for user {}.", userInServerId);
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to execute level actions for user {}.", userInServerId, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(aUserExperienceOptional.isEmpty()) {
|
||||
userExperienceManagementService.saveUser(aUserExperience);
|
||||
}
|
||||
if(!Objects.equals(result.getOldRoleId(), result.getNewRoleId())) {
|
||||
if(result.getOldRoleId() != null && result.getNewRoleId() != null) {
|
||||
roleService.updateRolesIds(member, List.of(result.getOldRoleId()), List.of(result.getNewRoleId())).thenAccept(unused -> {
|
||||
log.debug("Removed role {} from and added role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to remove role {} from and add role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
if(result.getOldRoleId() != null) {
|
||||
roleService.removeRoleFromMemberAsync(member, result.getOldRoleId()).thenAccept(unused -> {
|
||||
log.debug("Removed role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to remove role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(result.getNewRoleId() != null) {
|
||||
roleService.addRoleToMemberAsync(member, result.getNewRoleId()).thenAccept(unused -> {
|
||||
log.debug("Added role {} to member {} in server {}.", result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to add role {} to member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +521,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
public LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer) {
|
||||
log.debug("Retrieving rank for {}", userInAServer.getUserReference().getId());
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
|
||||
if(!aUserExperienceOptional.isPresent()) {
|
||||
if(aUserExperienceOptional.isEmpty()) {
|
||||
throw new NoExperienceTrackedException();
|
||||
}
|
||||
Integer rank = 0;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ExperienceLevelServiceBean implements ExperienceLevelService {
|
||||
if(level < 0) {
|
||||
throw new IllegalArgumentException("Level should not be less to 0.");
|
||||
}
|
||||
return 5L * (level * level) + 50 * level + 100;
|
||||
return 5L * ((long) level * level) + 50L * level + 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Override
|
||||
public CompletableFuture<Void> unsetRoles(List<ARole> rolesToUnset, GuildMessageChannel messageChannel) {
|
||||
List<AExperienceRole> rolesInServer = experienceRoleManagementService.getRolesInServer(rolesToUnset);
|
||||
Integer totalCount = 0;
|
||||
int totalCount = 0;
|
||||
for (AExperienceRole aExperienceRole : rolesInServer) {
|
||||
totalCount += aExperienceRole.getUsers().size();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
@@ -17,11 +20,9 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
@Component
|
||||
public class RunTimeExperienceService {
|
||||
|
||||
private Map<Long,Map<Long, Instant>> runtimeExperience = new HashMap<>();
|
||||
@Getter
|
||||
private final Map<Long,Map<Long, Instant>> runtimeExperience = new HashMap<>();
|
||||
private static final Lock lock = new ReentrantLock();
|
||||
public Map<Long, Map<Long, Instant>> getRuntimeExperience() {
|
||||
return runtimeExperience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires the lock of the runtime experience data structure. Operations on it should only be done, while holding the lock
|
||||
@@ -39,6 +40,7 @@ public class RunTimeExperienceService {
|
||||
|
||||
public void cleanupRunTimeStorage() {
|
||||
Instant now = Instant.now();
|
||||
Set<Long> serverIdsToRemove = new HashSet<>();
|
||||
runtimeExperience.forEach((serverId, userInstantMap) -> {
|
||||
List<Long> userIdsToRemove = new ArrayList<>();
|
||||
userInstantMap.forEach((userId, instant) -> {
|
||||
@@ -47,6 +49,10 @@ public class RunTimeExperienceService {
|
||||
}
|
||||
});
|
||||
userIdsToRemove.forEach(userInstantMap::remove);
|
||||
if(userInstantMap.isEmpty()) {
|
||||
serverIdsToRemove.add(serverId);
|
||||
}
|
||||
});
|
||||
serverIdsToRemove.forEach(runtimeExperience::remove);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RuntimeExperienceServiceTest {
|
||||
|
||||
@Test
|
||||
public void shouldCleanExpiredExperience() {
|
||||
RunTimeExperienceService experienceService = new RunTimeExperienceService();
|
||||
Map<Long, Instant> mapValue = new HashMap<>(Map.of(2L, Instant.now().minusSeconds(5)));
|
||||
experienceService.getRuntimeExperience().put(1L, mapValue);
|
||||
experienceService.cleanupRunTimeStorage();
|
||||
assertThat(experienceService.getRuntimeExperience()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLeaveExperienceIfNotYetExpired() {
|
||||
RunTimeExperienceService experienceService = new RunTimeExperienceService();
|
||||
Map<Long, Instant> mapValue2 = new HashMap<>(Map.of(3L, Instant.now().plusSeconds(5)));
|
||||
experienceService.getRuntimeExperience().put(2L, mapValue2);
|
||||
experienceService.cleanupRunTimeStorage();
|
||||
assertThat(experienceService.getRuntimeExperience().get(2L)).containsKey(3L);
|
||||
assertThat(experienceService.getRuntimeExperience()).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-impl</artifactId>
|
||||
|
||||
@@ -134,7 +134,7 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
if(giveawayCreationRequest.getTargetChannel() == null) {
|
||||
log.info("Sending giveaway to post target in server {}", serverId);
|
||||
postTargetService.validatePostTarget(GiveawayPostTarget.GIVEAWAYS, serverId);
|
||||
messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, GiveawayPostTarget.GIVEAWAYS, serverId);
|
||||
messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, GiveawayPostTarget.GIVEAWAYS, serverId).get(0);
|
||||
} else {
|
||||
log.info("Sending giveaway to channel {} in server {}.", giveawayCreationRequest.getTargetChannel().getId(), serverId);
|
||||
messageFutures = channelService.sendMessageToSendToChannel(messageToSend, giveawayCreationRequest.getTargetChannel());
|
||||
@@ -155,7 +155,7 @@ public class GiveawayServiceBean implements GiveawayService {
|
||||
Long giveawayId = giveaway.getGiveawayId().getId();
|
||||
log.info("Adding giveaway participating of user {} to giveaway {} in server {}.", member.getIdLong(), giveawayId, member.getGuild().getIdLong());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, giveawayMessageModel, member.getGuild().getIdLong());
|
||||
return channelService.editEmbedMessageInAChannel(messageToSend.getEmbeds().get(0), messageChannel, giveaway.getMessageId())
|
||||
return channelService.editMessageInAChannelFuture(messageToSend, messageChannel, giveaway.getMessageId())
|
||||
.thenAccept(message -> {
|
||||
self.persistAddedParticipant(member, giveawayId);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -254,8 +254,8 @@ public class InviteLinkFilterServiceBean implements InviteLinkFilterService {
|
||||
log.info("Sending notification about {} deleted invite links in guild {} from user {} in channel {} in message {}.",
|
||||
codes.size(), serverId, message.getAuthor().getIdLong(), message.getChannel().getIdLong(), message.getIdLong());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(INVITE_LINK_DELETED_NOTIFICATION_EMBED_TEMPLATE_KEY, model, message.getGuild().getIdLong());
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, InviteFilterPostTarget.INVITE_DELETE_LOG, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures).thenAccept(unused ->
|
||||
List<List<CompletableFuture<Message>>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, InviteFilterPostTarget.INVITE_DELETE_LOG, serverId);
|
||||
return FutureUtils.toSingleFutureGenericList(messageFutures).thenAccept(unused ->
|
||||
log.debug("Successfully send notification about deleted invite link in message {}.", message.getIdLong())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-int</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -13,9 +13,13 @@ import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.Event;
|
||||
@@ -27,7 +31,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -67,37 +70,51 @@ public class MessageEmbedListener implements MessageReceivedListener {
|
||||
}
|
||||
String messageRaw = message.getContentRaw();
|
||||
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
|
||||
for (MessageEmbedLink messageEmbedLink : links) {
|
||||
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
|
||||
}
|
||||
boolean deleteMessage = StringUtils.isBlank(messageRaw) && !links.isEmpty() && message.getAttachments().isEmpty();
|
||||
if(!links.isEmpty()) {
|
||||
Long messageId = message.getIdLong();
|
||||
Long channelId = message.getChannelIdLong();
|
||||
Long serverId = message.getGuildIdLong();
|
||||
log.debug("We found {} links to embed in message {} in channel {} in guild {}.", links.size(), message.getId(), message.getChannel().getId(), message.getGuild().getId());
|
||||
Long userEmbeddingUserInServerId = userInServerManagementService.loadOrCreateUser(message.getMember()).getUserInServerId();
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
for (MessageEmbedLink messageEmbedLink : links) {
|
||||
// potentially support foreign linked servers
|
||||
// potentially support foreign linked servers?
|
||||
if(!messageEmbedLink.getServerId().equals(message.getGuild().getIdLong())) {
|
||||
log.info("Link for message {} was from a foreign server {}. Do not embed.", messageEmbedLink.getMessageId(), messageEmbedLink.getServerId());
|
||||
continue;
|
||||
}
|
||||
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
|
||||
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenAccept(cachedMessageConsumer)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Error when embedding link for message {}", message.getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
Function<CachedMessage, CompletableFuture<Void>> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
|
||||
futures.add(messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenCompose(cachedMessageConsumer));
|
||||
}
|
||||
if(!futures.isEmpty()) {
|
||||
// only delete the message if all futures go through
|
||||
new CompletableFutureList<>(futures).getMainFuture().thenAccept(unused -> {
|
||||
if(deleteMessage) {
|
||||
messageService.deleteMessageInChannelInServer(serverId, channelId, messageId);
|
||||
}
|
||||
}).thenAccept(unused -> {
|
||||
log.info("Deleted embedding message server {} channel {} message {}.", serverId, channelId, messageId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.info("Failed to delete embedding message or to embed message server {} channel {} message {}.", serverId, channelId, messageId, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
if(StringUtils.isBlank(messageRaw) && !links.isEmpty() && message.getAttachments().isEmpty()) {
|
||||
messageService.deleteMessage(message);
|
||||
if(deleteMessage) {
|
||||
return ConsumableListenerResult.DELETED;
|
||||
}
|
||||
if(!links.isEmpty()) {
|
||||
} else if(!links.isEmpty()) {
|
||||
return ConsumableListenerResult.PROCESSED;
|
||||
}
|
||||
return ConsumableListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
|
||||
public CompletableFuture<Void> embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
|
||||
GuildMemberMessageChannel context = GuildMemberMessageChannel
|
||||
.builder()
|
||||
.guildChannel(message.getGuildChannel())
|
||||
@@ -107,7 +124,7 @@ public class MessageEmbedListener implements MessageReceivedListener {
|
||||
.build();
|
||||
log.info("Embedding link to message {} in channel {} in server {} to channel {} and server {}.",
|
||||
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), message.getChannel().getId(), message.getGuild().getId());
|
||||
messageEmbedService.embedLink(cachedMessage, message.getGuildChannel(), cause , context).thenAccept(unused ->
|
||||
return messageEmbedService.embedLink(cachedMessage, message.getGuildChannel(), cause , context).thenAccept(unused ->
|
||||
metricService.incrementCounter(MESSAGE_EMBED_CREATED)
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Failed to embed link towards message {} in channel {} in sever {} linked from message {} in channel {} in server {}.", cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class JoinLogger implements AsyncJoinListener {
|
||||
.build();
|
||||
log.debug("Logging join event for user {} in server {}.", listenerModel.getMember().getIdLong(), listenerModel.getServerId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(USER_JOIN_TEMPLATE, model, listenerModel.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, LoggingPostTarget.JOIN_LOG, listenerModel.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, LoggingPostTarget.JOIN_LOG, listenerModel.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send member joining log.", throwable);
|
||||
return null;
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncLeaveListener;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.listener.MemberLeaveModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
@@ -13,6 +14,7 @@ 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.MemberLeaveLogModel;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -41,14 +43,21 @@ public class LeaveLogger implements AsyncLeaveListener {
|
||||
.userId(listenerModel.getUser().getIdLong())
|
||||
.serverId(listenerModel.getServerId())
|
||||
.build();
|
||||
List<RoleDisplay> roles = listenerModel
|
||||
.getMember()
|
||||
.getRoles()
|
||||
.stream()
|
||||
.map(RoleDisplay::fromRole)
|
||||
.toList();
|
||||
MemberLeaveLogModel model = MemberLeaveLogModel
|
||||
.builder()
|
||||
.leavingUser(leavingUser)
|
||||
.user(UserDisplay.fromUser(listenerModel.getUser()))
|
||||
.roles(roles)
|
||||
.build();
|
||||
log.debug("Logging leave event for user {} in server {}.", listenerModel.getUser().getIdLong(), listenerModel.getServerId());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(USER_LEAVE_TEMPLATE, model, listenerModel.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, LoggingPostTarget.LEAVE_LOG, listenerModel.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, LoggingPostTarget.LEAVE_LOG, listenerModel.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send member leaving log.", throwable);
|
||||
return null;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class MessageDeleteLogListener implements AsyncMessageDeletedListener {
|
||||
.member(authorMember)
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_DELETED_TEMPLATE, logModel, messageFromCache.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send message deleted log.", throwable);
|
||||
return null;
|
||||
@@ -86,7 +86,7 @@ public class MessageDeleteLogListener implements AsyncMessageDeletedListener {
|
||||
.member(authorMember)
|
||||
.build();
|
||||
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_DELETED_ATTACHMENT_TEMPLATE, attachmentLogModel, messageFromCache.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageFromCache.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send message deleted log.", throwable);
|
||||
return null;
|
||||
|
||||
@@ -66,7 +66,7 @@ public class MessageEditedListener implements AsyncMessageUpdatedListener {
|
||||
.member(messageAfter.getMember())
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, lodModel, model.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.EDIT_LOG, model.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(message, LoggingPostTarget.EDIT_LOG, model.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send message edited log.", throwable);
|
||||
return null;
|
||||
@@ -90,7 +90,7 @@ public class MessageEditedListener implements AsyncMessageUpdatedListener {
|
||||
.build();
|
||||
MessageToSend attachmentEmbed = templateService.renderEmbedTemplate(MESSAGE_EDITED_ATTACHMENT_REMOVED_TEMPLATE,
|
||||
attachmentModel, messageBefore.getServerId());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageBefore.getServerId()))
|
||||
FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(attachmentEmbed, LoggingPostTarget.DELETE_LOG, messageBefore.getServerId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to send message edited attachment log.", throwable);
|
||||
return null;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.sheldan.abstracto.logging.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import java.util.List;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -12,4 +14,5 @@ import lombok.Setter;
|
||||
public class MemberLeaveLogModel {
|
||||
private ServerUser leavingUser;
|
||||
private UserDisplay user;
|
||||
private List<RoleDisplay> roles;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -76,16 +75,15 @@ public class Ban extends AbstractConditionableCommand {
|
||||
duration = null;
|
||||
}
|
||||
|
||||
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||
if(member != null) {
|
||||
return event.deferReply().submit()
|
||||
.thenCompose((hook) -> self.banMember(event, member, reason, duration, hook))
|
||||
.thenApply(commandResult -> CommandResult.fromSuccess());
|
||||
} else {
|
||||
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
||||
Long userId = Long.parseLong(userIdStr);
|
||||
User user = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, User.class);
|
||||
return event.deferReply().submit()
|
||||
.thenCompose((hook) -> self.banViaUserId(event, userId, reason, duration, hook))
|
||||
.thenCompose((hook) -> self.banViaUserId(event, user.getIdLong(), reason, duration, hook))
|
||||
.thenApply(commandResult -> CommandResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package dev.sheldan.abstracto.moderation.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.listener.HoneyPotServiceBean;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.HoneyPotBanResponseModel;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
@Component
|
||||
public class HoneyPotBan extends AbstractConditionableCommand {
|
||||
|
||||
private static final String DURATION_PARAMETER = "duration";
|
||||
private static final String HONEYPOT_BAN_RESPONSE = "honeypotBan_response";
|
||||
private static final String HONEYPOT_BAN_COMMAND = "honeypotBan";
|
||||
|
||||
@Autowired
|
||||
private HoneyPotBan self;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private HoneyPotServiceBean honeyPotServiceBean;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Duration duration;
|
||||
if(slashCommandParameterService.hasCommandOption(DURATION_PARAMETER, event)) {
|
||||
String durationStr = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||
duration = ParseUtils.parseDuration(durationStr);
|
||||
} else {
|
||||
Long ignoredSeconds =
|
||||
configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, event.getGuild().getIdLong());
|
||||
duration = Duration.ofSeconds(ignoredSeconds);
|
||||
}
|
||||
|
||||
return event.deferReply(false).submit()
|
||||
.thenCompose(hook -> self.banEveryHoneypotMember(hook, event.getGuild(), duration))
|
||||
.thenCompose(banResponse -> self.sendResponse(banResponse))
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendResponse(Pair<InteractionHook, Integer> banResponse) {
|
||||
HoneyPotBanResponseModel responseModel = HoneyPotBanResponseModel
|
||||
.builder()
|
||||
.bannedMemberCount(banResponse.getRight())
|
||||
.build();
|
||||
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(HONEYPOT_BAN_RESPONSE, responseModel, banResponse.getLeft()));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Pair<InteractionHook, Integer>> banEveryHoneypotMember(InteractionHook hook, Guild guild, Duration duration) {
|
||||
Instant maxJoinAge;
|
||||
if(duration != null) {
|
||||
maxJoinAge = Instant.now().minus(duration);
|
||||
} else {
|
||||
maxJoinAge = Instant.now();
|
||||
}
|
||||
List<Member> currentMembersWithHoneypotRole = honeyPotServiceBean.getCurrentMembersWithHoneypotRole(guild)
|
||||
.stream().filter(member -> member.getTimeJoined().toInstant().isBefore(maxJoinAge))
|
||||
.toList();
|
||||
Role honeyPotRole = guild.getRoleById(honeyPotServiceBean.getHoneyPotRoleId(guild.getIdLong()));
|
||||
List<CompletableFuture<Void>> futures = currentMembersWithHoneypotRole.stream().map(member ->
|
||||
honeyPotServiceBean.banForHoneyPot(member, honeyPotRole)
|
||||
).toList();
|
||||
Integer memberCount = currentMembersWithHoneypotRole.size();
|
||||
CompletableFutureList<Void> futureList = new CompletableFutureList<>(futures);
|
||||
return futureList.getMainFuture()
|
||||
.thenApply(unused -> Pair.of(hook, memberCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
Parameter durationParameter = Parameter
|
||||
.builder()
|
||||
.name(DURATION_PARAMETER)
|
||||
.templated(true)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(durationParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.hasExample(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(ModerationSlashCommandNames.MODERATION)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.commandName("honeypotban")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(HONEYPOT_BAN_COMMAND)
|
||||
.module(ModerationModuleDefinition.MODERATION)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.slashCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.HONEYPOT;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,6 @@ import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -86,16 +85,15 @@ public class Infractions extends AbstractConditionableCommand {
|
||||
public CompletableFuture<CommandResult> showInfractions(InteractionHook hook, SlashCommandInteractionEvent event) {
|
||||
List<Infraction> infractions;
|
||||
Guild guild = hook.getInteraction().getGuild();
|
||||
if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.USER)) {
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||
Member member = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, Member.class);
|
||||
User user = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, User.class);
|
||||
if(member != null) {
|
||||
if(!member.getGuild().equals(guild)) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
infractions = infractionManagementService.getInfractionsForUser(userInServerManagementService.loadOrCreateUser(member));
|
||||
} else if(slashCommandParameterService.hasCommandOptionWithFullType(USER_PARAMETER, event, OptionType.STRING)){
|
||||
String userIdStr = slashCommandParameterService.getCommandOption(USER_PARAMETER, event, User.class, String.class);
|
||||
Long userId = Long.parseLong(userIdStr);
|
||||
AUserInAServer userInServer = userInServerManagementService.loadOrCreateUser(guild.getIdLong(), userId);
|
||||
} else if(user != null){
|
||||
AUserInAServer userInServer = userInServerManagementService.loadOrCreateUser(guild.getIdLong(), user.getIdLong());
|
||||
infractions = infractionManagementService.getInfractionsForUser(userInServer);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BanModerationActionModalListener implements ModalInteractionListene
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getDurationInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
@@ -76,7 +76,7 @@ public class BanModerationActionModalListener implements ModalInteractionListene
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -4,97 +4,44 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.jda.RoleAddedListener;
|
||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.listener.RoleAddedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ConditionService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.service.SystemCondition;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel;
|
||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.ISnowflake;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class HoneyPotRoleAddedListener implements RoleAddedListener {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private BanService banService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ConditionService conditionService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
private static final String HONEYPOT_BAN_REASON_TEMPLATE = "honeypot_ban_reason";
|
||||
|
||||
private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId";
|
||||
private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level";
|
||||
private static final String LEVEL_CONDITION_SERVER_PARAMETER = "serverId";
|
||||
|
||||
private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL";
|
||||
@Autowired
|
||||
private HoneyPotServiceBean honeyPotServiceBean;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(RoleAddedModel model) {
|
||||
Long honeyPotRoleId = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_ROLE_ID, model.getServerId());
|
||||
Long honeyPotRoleId = honeyPotServiceBean.getHoneyPotRoleId(model.getServerId());
|
||||
if(honeyPotRoleId == 0) {
|
||||
log.info("Server {} has honeypot feature enabled, but still default honeypot role config - Ignoring.", model.getServerId());
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
if(honeyPotRoleId.equals(model.getRoleId())) {
|
||||
Integer levelToSkipBan = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_LEVEL, model.getServerId()).intValue();
|
||||
Long amountOfSecondsToIgnore = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, model.getServerId());
|
||||
boolean allowed = userHasLevel(model.getTargetMember(), levelToSkipBan) || userJoinedLongerThanSeconds(model.getTargetMember(), amountOfSecondsToIgnore);
|
||||
if(allowed) {
|
||||
log.info("User {} in server {} has at least level {} or joined more than {} seconds ago and will not get banned by honeypot. All existing roles besides {} will be removed.",
|
||||
model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), levelToSkipBan, amountOfSecondsToIgnore, honeyPotRoleId);
|
||||
cleanupRolesBesidesHoneyPot(model, honeyPotRoleId);
|
||||
} else {
|
||||
boolean fellIntoHoneyPot = honeyPotServiceBean.fellIntoHoneyPot(model.getServerId(), model.getTargetMember());
|
||||
if (fellIntoHoneyPot) {
|
||||
log.info("Banning user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId());
|
||||
HoneyPotReasonModel reasonModel = HoneyPotReasonModel
|
||||
.builder()
|
||||
.memberDisplay(MemberDisplay.fromMember(model.getTargetMember()))
|
||||
.roleDisplay(RoleDisplay.fromRole(model.getRole()))
|
||||
.build();
|
||||
String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel, model.getServerId());
|
||||
banService.banUserWithNotification(model.getTargetUser(), banReason, ServerUser.fromMember(model.getTargetMember().getGuild().getSelfMember()),
|
||||
model.getTargetMember().getGuild(), Duration.ofDays(7)).thenAccept(banResult -> {
|
||||
log.info("Banned user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId());
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to ban user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId(), throwable);
|
||||
return null;
|
||||
});
|
||||
honeyPotServiceBean.banForHoneyPot(model.getTargetMember(), model.getRole());
|
||||
} else {
|
||||
log.info("User {} in server {} will not get banned by honeypot. All existing roles besides {} will be removed.",
|
||||
model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), honeyPotRoleId);
|
||||
cleanupRolesBesidesHoneyPot(model, honeyPotRoleId);
|
||||
}
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
} else {
|
||||
@@ -126,28 +73,6 @@ public class HoneyPotRoleAddedListener implements RoleAddedListener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean userHasLevel(Member member, Integer level) {
|
||||
log.info("Checking if member {} is ignored to click on the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong());
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
|
||||
parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level);
|
||||
parameters.put(LEVEL_CONDITION_SERVER_PARAMETER, member.getGuild().getIdLong());
|
||||
ConditionContextInstance contextInstance = ConditionContextInstance
|
||||
.builder()
|
||||
.conditionName(LEVEL_CONDITION_NAME)
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
SystemCondition.Result result = conditionService.checkConditions(contextInstance);
|
||||
return SystemCondition.Result.isSuccessful(result);
|
||||
}
|
||||
|
||||
private boolean userJoinedLongerThanSeconds(Member member, Long seconds) {
|
||||
log.info("Checking if member {} joined the server more than {} seconds ago.", member.getIdLong(), seconds);
|
||||
// the incorrectness of timejoined should not matter, we chunk anyway
|
||||
return member.getTimeJoined().toInstant().isBefore(Instant.now().minus(seconds, ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.HONEYPOT;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ConditionService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.service.SystemCondition;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel;
|
||||
import dev.sheldan.abstracto.moderation.service.BanService;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
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;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class HoneyPotServiceBean {
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ConditionService conditionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private BanService banService;
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId";
|
||||
private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level";
|
||||
private static final String LEVEL_CONDITION_SERVER_PARAMETER = "serverId";
|
||||
private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL";
|
||||
private static final String HONEYPOT_BAN_REASON_TEMPLATE = "honeypot_ban_reason";
|
||||
|
||||
|
||||
public Long getHoneyPotRoleId(Long serverId) {
|
||||
return configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_ROLE_ID, serverId);
|
||||
}
|
||||
|
||||
public boolean fellIntoHoneyPot(Long serverId, Member member) {
|
||||
Integer levelToSkipBan = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_LEVEL, serverId).intValue();
|
||||
Long amountOfSecondsToIgnore = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, serverId);
|
||||
boolean allowed = userHasLevel(member, levelToSkipBan) || userJoinedLongerThanSeconds(member, amountOfSecondsToIgnore);
|
||||
return !allowed;
|
||||
}
|
||||
|
||||
public List<Member> getCurrentMembersWithHoneypotRole(Guild guild) {
|
||||
return memberService.getMembersWithRole(guild.getIdLong(), getHoneyPotRoleId(guild.getIdLong()));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> banForHoneyPot(Member targetMember, Role role) {
|
||||
HoneyPotReasonModel reasonModel = HoneyPotReasonModel
|
||||
.builder()
|
||||
.memberDisplay(MemberDisplay.fromMember(targetMember))
|
||||
.roleDisplay(RoleDisplay.fromRole(role))
|
||||
.build();
|
||||
ServerUser bannedUser = ServerUser.fromMember(targetMember);
|
||||
String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel, bannedUser.getServerId());
|
||||
long roleId = role.getIdLong();
|
||||
return banService.banUserWithNotification(bannedUser, banReason, ServerUser.fromMember(targetMember.getGuild().getSelfMember()),
|
||||
targetMember.getGuild(), Duration.ofDays(7)).thenAccept(banResult -> {
|
||||
log.info("Banned user {} in guild {} due to role {}.", bannedUser.getUserId(), bannedUser.getServerId(), roleId);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to ban user {} in guild {} due to role {}.", bannedUser.getUserId(), bannedUser.getServerId(), roleId, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private boolean userHasLevel(Member member, Integer level) {
|
||||
log.info("Checking if member {} is ignored to click on the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong());
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
|
||||
parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level);
|
||||
parameters.put(LEVEL_CONDITION_SERVER_PARAMETER, member.getGuild().getIdLong());
|
||||
ConditionContextInstance contextInstance = ConditionContextInstance
|
||||
.builder()
|
||||
.conditionName(LEVEL_CONDITION_NAME)
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
SystemCondition.Result result = conditionService.checkConditions(contextInstance);
|
||||
return SystemCondition.Result.isSuccessful(result);
|
||||
}
|
||||
|
||||
private boolean userJoinedLongerThanSeconds(Member member, Long seconds) {
|
||||
log.info("Checking if member {} joined the server more than {} seconds ago.", member.getIdLong(), seconds);
|
||||
// the incorrectness of timejoined should not matter, we chunk anyway
|
||||
return member.getTimeJoined().toInstant().isBefore(Instant.now().minus(seconds, ChronoUnit.SECONDS));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class KickModerationActionModalListener implements ModalInteractionListen
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MuteModerationActionModalListener implements ModalInteractionListen
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
@@ -68,7 +68,7 @@ public class MuteModerationActionModalListener implements ModalInteractionListen
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getDurationInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -60,7 +60,7 @@ public class WarnModerationActionModalListener implements ModalInteractionListen
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ReportContextModalListener implements ModalInteractionListener {
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getTextInputId()))
|
||||
.filter(modalMapping -> modalMapping.getCustomId().equals(payload.getTextInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -168,14 +168,14 @@ public class BanServiceBean implements BanService {
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendUnBanLogMessage(UserUnBannedLogModel model, Long serverId) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(USER_UN_BANNED_NOTIFICATION_TEMPLATE, model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, ModerationPostTarget.BAN_LOG, serverId));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, ModerationPostTarget.BAN_LOG, serverId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendBanLogMessage(UserBannedLogModel model, Long serverId) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(USER_BANNED_NOTIFICATION_TEMPLATE, model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, ModerationPostTarget.BAN_LOG, serverId));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, ModerationPostTarget.BAN_LOG, serverId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public class InfractionServiceBean implements InfractionService {
|
||||
.build();
|
||||
infractionLevelChangedListenerManager.sendInfractionLevelChangedEvent(newLevel, oldLevel, currentPoints, oldPoints, ServerUser.fromAUserInAServer(aUserInAServer));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(INFRACTION_NOTIFICATION_TEMPLATE_KEY, model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, InfractionPostTarget.INFRACTION_NOTIFICATION, serverId));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, InfractionPostTarget.INFRACTION_NOTIFICATION, serverId));
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,9 @@ public class KickServiceBean implements KickService {
|
||||
public CompletableFuture<Void> kickMember(Member kickedMember, Member kickingMember, String reason) {
|
||||
Guild guild = kickedMember.getGuild();
|
||||
log.info("Kicking user {} from guild {}", kickedMember.getUser().getIdLong(), guild.getIdLong());
|
||||
CompletableFuture<Void> kickFuture = guild.kick(kickedMember, reason).submit();
|
||||
CompletableFuture<Void> kickFuture = guild.kick(kickedMember)
|
||||
.reason(reason)
|
||||
.submit();
|
||||
CompletableFuture<Message> logFuture = sendKickLog(kickedMember.getUser(), ServerUser.fromMember(kickedMember), kickingMember.getUser(), ServerUser.fromMember(kickingMember), reason, guild.getIdLong());
|
||||
return CompletableFuture.allOf(kickFuture, logFuture)
|
||||
.thenAccept(unused -> self.storeInfraction(kickedMember, kickingMember, reason, logFuture.join(), guild.getIdLong()));
|
||||
@@ -125,7 +127,7 @@ public class KickServiceBean implements KickService {
|
||||
public CompletableFuture<Message> sendKicklog(KickLogModel kickLogModel, Long serverId) {
|
||||
MessageToSend warnLogMessage = templateService.renderEmbedTemplate(KICK_LOG_TEMPLATE, kickLogModel, serverId);
|
||||
log.debug("Sending kick log message in guild {}.", serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(warnLogMessage, ModerationPostTarget.KICK_LOG, serverId).get(0);
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures).thenApply(unused -> messageFutures.get(0).join());
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ public class MuteServiceBean implements MuteService {
|
||||
@Override
|
||||
public CompletableFuture<Void> sendMuteLogMessage(MuteLogModel model, Long serverId) {
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MuteServiceBean.MUTE_LOG_TEMPLATE, model, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, serverId));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, serverId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -114,7 +114,7 @@ public class ReactionReportServiceBean implements ReactionReportService {
|
||||
.reportedMessage(reportedMessage)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(REACTION_REPORT_TEMPLATE_KEY, model, serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, ReactionReportPostTarget.REACTION_REPORTS, serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, ReactionReportPostTarget.REACTION_REPORTS, serverId).get(0);
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures)
|
||||
.thenAccept(unused -> reportMessageCreatedListenerManager.sendReportMessageCreatedEvent(reportedMessage, messageFutures.get(0).join(), anonymous ? null : reporter))
|
||||
.thenAccept(unused -> {
|
||||
|
||||
@@ -120,7 +120,7 @@ public class WarnServiceBean implements WarnService {
|
||||
.reason(reason)
|
||||
.build();
|
||||
MessageToSend message = renderMessageModel(warnContext, guild.getIdLong());
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, guild.getIdLong());
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, WarningPostTarget.WARN_LOG, guild.getIdLong()).get(0);
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenCompose(unused -> futures.get(0));
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ public class WarnServiceBean implements WarnService {
|
||||
.warnings(warnDecayWarnings)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(WARN_DECAY_LOG_TEMPLATE_KEY, warnDecayLogModel, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId()));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, WarnDecayPostTarget.DECAY_LOG, server.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<property name="moderationModule" value="(SELECT id FROM module WHERE name = 'moderation')"/>
|
||||
<property name="honeypotFeature" value="(SELECT id FROM feature WHERE key = 'honeypot')"/>
|
||||
|
||||
<changeSet author="Sheldan" id="honeypotBan-command">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="honeypotBan"/>
|
||||
<column name="module_id" valueComputed="${moderationModule}"/>
|
||||
<column name="feature_id" valueComputed="${honeypotFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -13,4 +13,5 @@
|
||||
<include file="1.4.3/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.10/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.23/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.6.21/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class HoneyPotBanResponseModel {
|
||||
private Integer bannedMemberCount;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
public CompletableFuture<Void> sendModMailNotification(User user, GuildMessageChannel channel, boolean appeal) {
|
||||
Long serverId = channel.getGuild().getIdLong();
|
||||
MessageToSend messageToSend = getModmailNotificationMessageToSend(user, channel, serverId, true, appeal);
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_PING, serverId));
|
||||
return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_PING, serverId));
|
||||
}
|
||||
|
||||
private MessageToSend getModmailNotificationMessageToSend(User user, GuildMessageChannel channel, Long serverId, boolean pingRole, boolean appeal) {
|
||||
@@ -1023,7 +1023,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
||||
return channelService.sendMessageEmbedToSendToAChannel(messageToSend, modMailThread.getChannel());
|
||||
} else {
|
||||
return postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_LOG, model.getServerId());
|
||||
return postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_LOG, model.getServerId()).get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1064,7 +1064,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
ModMailLoggedMessageModel message = loadedMessages.get(i);
|
||||
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());
|
||||
List<CompletableFuture<Message>> logFuture = postTargetService.sendEmbedInPostTarget(messageToSend, ModMailPostTargets.MOD_MAIL_LOG, updateMessage.getGuild().getIdLong()).get(0);
|
||||
if(i != 0 && (i % 10) == 0) {
|
||||
progressModel.setLoggedMessages(i);
|
||||
messageService.editMessageWithNewTemplate(updateMessage, MODMAIL_CLOSE_PROGRESS_TEMPLATE_KEY, progressModel);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ public class ProfanityFilterServiceBean implements ProfanityFilterService {
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(PROFANITY_REPORT_TEMPLATE_KEY, reportModel, serverId);
|
||||
List<CompletableFuture<Message>> messageFutures = postTargetService
|
||||
.sendEmbedInPostTarget(messageToSend, ProfanityFilterPostTarget.PROFANITY_FILTER_QUEUE, serverId);
|
||||
.sendEmbedInPostTarget(messageToSend, ProfanityFilterPostTarget.PROFANITY_FILTER_QUEUE, serverId).get(0);
|
||||
Long profanityRegexId = foundProfanityRegex.getId();
|
||||
return FutureUtils.toSingleFutureGeneric(messageFutures).thenCompose(aVoid -> {
|
||||
Message createdMessage = messageFutures.get(0).join();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -130,13 +130,14 @@ public class RemindServiceBean implements ReminderService {
|
||||
if(remindIn.getSeconds() < 60) {
|
||||
reminder.setJobTriggerKey(null);
|
||||
log.info("Directly scheduling unremind for reminder {}, because it was below the threshold.", reminder.getId());
|
||||
long nanos = Math.max(remindIn.toNanos(), Duration.ofSeconds(5).toNanos()); // should be good enough, if its too small, it doesnt find the reminder
|
||||
instantReminderScheduler.schedule(() -> {
|
||||
try {
|
||||
self.executeReminder(reminder.getId());
|
||||
} catch (Exception exception) {
|
||||
log.error("Failed to remind immediately.", exception);
|
||||
}
|
||||
}, remindIn.toNanos(), TimeUnit.NANOSECONDS);
|
||||
}, nanos, TimeUnit.NANOSECONDS);
|
||||
} else {
|
||||
HashMap<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put("reminderId", reminder.getId().toString());
|
||||
@@ -223,6 +224,9 @@ public class RemindServiceBean implements ReminderService {
|
||||
.builder()
|
||||
.reminderParticipants(participantsDisplays)
|
||||
.reminderDisplay(reminderDisplay)
|
||||
.serverId(reminder.getServer().getId())
|
||||
.channelId(reminder.getChannel().getId())
|
||||
.messageId(reminder.getMessageId())
|
||||
.userDisplay(UserDisplay.fromUser(member.getUser()))
|
||||
.duration(Duration.between(reminder.getReminderDate(), reminder.getTargetDate()))
|
||||
.build();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.database.PostTarget;
|
||||
import dev.sheldan.abstracto.core.models.property.SystemConfigProperty;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
|
||||
@@ -116,7 +118,7 @@ public class StarboardServiceBean implements StarboardService {
|
||||
public CompletionStage<Void> sendStarboardPostAndStore(CachedMessage message, Long starredUserId, List<Long> userExceptAuthorIds, StarboardPostModel starboardPostModel, Long userReactingId) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel, message.getServerId());
|
||||
PostTarget starboard = postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), message.getServerId());
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, message.getServerId());
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, message.getServerId()).get(0);
|
||||
Long starboardChannelId = starboard.getChannelReference().getId();
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
|
||||
self.persistPost(message, userExceptAuthorIds, completableFutures, starboardChannelId, starredUserId, userReactingId)
|
||||
@@ -148,22 +150,43 @@ public class StarboardServiceBean implements StarboardService {
|
||||
|
||||
|
||||
private CompletableFuture<StarboardPostModel> buildStarboardPostModel(CachedMessage message, Integer starCount) {
|
||||
return userService.retrieveUserForId(message.getAuthor().getAuthorId())
|
||||
.thenApply(user -> createStarboardModel(message, starCount, user))
|
||||
CompletableFuture<User> userFuture = userService.retrieveUserForId(message.getAuthor().getAuthorId());
|
||||
CompletableFuture<Member> memberFuture = memberService.retrieveMemberInServer(message.getAuthorAsServerUser());
|
||||
CompletableFuture<StarboardPostModel> returnedFuture = new CompletableFuture<>();
|
||||
FutureUtils.toSingleFuture(List.of(userFuture, memberFuture))
|
||||
.whenComplete((any, error) -> {
|
||||
User user = null;
|
||||
if(!userFuture.isCompletedExceptionally()) {
|
||||
user = userFuture.join();
|
||||
} else {
|
||||
log.warn("Failed to retrieve user for author {} of starboard post.", message.getAuthor().getAuthorId());
|
||||
}
|
||||
Member member = null;
|
||||
if(!memberFuture.isCompletedExceptionally()) {
|
||||
member = memberFuture.join();
|
||||
} else {
|
||||
log.warn("Failed to retrieve user for author {} of starboard post.", message.getAuthor().getAuthorId());
|
||||
}
|
||||
StarboardPostModel starboardModel = createStarboardModel(message, starCount, user, member);
|
||||
returnedFuture.complete(starboardModel);
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
log.warn("Failed to retrieve user for author {} of starboard post.", message.getAuthor().getAuthorId(), throwable);
|
||||
return createStarboardModel(message, starCount, null);
|
||||
log.warn("Complete failure when handling creation starboard post of message {}.", message.getMessageId(), throwable);
|
||||
returnedFuture.completeExceptionally(throwable);
|
||||
return null;
|
||||
});
|
||||
return returnedFuture;
|
||||
}
|
||||
|
||||
private StarboardPostModel createStarboardModel(CachedMessage message, Integer starCount, net.dv8tion.jda.api.entities.User user) {
|
||||
private StarboardPostModel createStarboardModel(CachedMessage message, Integer starCount, net.dv8tion.jda.api.entities.User user, Member member) {
|
||||
Optional<GuildMessageChannel> channel = channelService.getMessageChannelFromServerOptional(message.getServerId(), message.getChannelId());
|
||||
Optional<Guild> guild = guildService.getGuildByIdOptional(message.getServerId());
|
||||
String starLevelEmote = getAppropriateEmote(message.getServerId(), starCount);
|
||||
return StarboardPostModel
|
||||
.builder()
|
||||
.message(message)
|
||||
.author(user)
|
||||
.authorUser(user != null ? UserDisplay.fromUser(user) : null)
|
||||
.authorMember(member != null ? MemberDisplay.fromMember(member) : null)
|
||||
.sourceChannelId(message.getChannelId())
|
||||
.channel(channel.orElse(null))
|
||||
.starCount(starCount)
|
||||
@@ -214,7 +237,7 @@ public class StarboardServiceBean implements StarboardService {
|
||||
int count = 3;
|
||||
List<CompletableFuture<StarStatsUser>> topStarGiverFutures = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);
|
||||
List<CompletableFuture<StarStatsUser>> topStarReceiverFutures = starboardPostReactorManagementService.retrieveTopStarReceiver(serverId, count);
|
||||
List<CompletableFuture> allFutures = new ArrayList<>();
|
||||
List<CompletableFuture<?>> allFutures = new ArrayList<>();
|
||||
allFutures.addAll(topStarGiverFutures);
|
||||
allFutures.addAll(topStarReceiverFutures);
|
||||
return FutureUtils.toSingleFuture(allFutures).thenApply(aVoid -> {
|
||||
|
||||
@@ -185,7 +185,7 @@ public class StarboardServiceBeanTest {
|
||||
when(postTarget.getChannelReference()).thenReturn(starboardChannel);
|
||||
when(starboardChannel.getId()).thenReturn(STARBOARD_CHANNEL_ID);
|
||||
when(postTargetManagement.getPostTarget(StarboardPostTarget.STARBOARD.getKey(), SERVER_ID)).thenReturn(postTarget);
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, SERVER_ID)).thenReturn(Arrays.asList(CompletableFuture.completedFuture(null)));
|
||||
when(postTargetService.sendEmbedInPostTarget(messageToSend, StarboardPostTarget.STARBOARD, SERVER_ID)).thenReturn(List.of(List.of(CompletableFuture.completedFuture(null))));
|
||||
ArrayList<Long> userExceptAuthorIds = new ArrayList<>();
|
||||
testUnit.sendStarboardPostAndStore(message, STARRED_USER_ID, userExceptAuthorIds, model, STARRING_USER_ID);
|
||||
verify(self, times(1)).persistPost(eq(message), eq(userExceptAuthorIds), any(), eq(STARBOARD_CHANNEL_ID), eq(STARRED_USER_ID), eq(STARRING_USER_ID));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,17 +2,19 @@ package dev.sheldan.abstracto.starboard.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.context.ServerContext;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class StarboardPostModel extends ServerContext {
|
||||
private User author;
|
||||
private UserDisplay authorUser;
|
||||
private MemberDisplay authorMember;
|
||||
private GuildMessageChannel channel;
|
||||
private Long sourceChannelId;
|
||||
private CachedMessage message;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.6.10-SNAPSHOT</version>
|
||||
<version>1.6.21-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user