mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-21 07:10:26 +00:00
Compare commits
18 Commits
abstracto-
...
abstracto-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
118b4c0e5d | ||
|
|
95a639a733 | ||
|
|
919b52a607 | ||
|
|
a9229d4b28 | ||
|
|
47ce03ac25 | ||
|
|
cef96515aa | ||
|
|
23ac70bb69 | ||
|
|
072d680e2f | ||
|
|
04b3e073aa | ||
|
|
08e2a31f15 | ||
|
|
184271ff7c | ||
|
|
c4fe73b3f8 | ||
|
|
2dc73ef3b9 | ||
|
|
2dd02cdae8 | ||
|
|
d39ee4359f | ||
|
|
d7cc7f579f | ||
|
|
7d30afbd2c | ||
|
|
f4c1dcb27f |
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</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.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -151,6 +151,11 @@ public class EntertainmentServiceBean implements EntertainmentService {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(replacedCombos.contains(charAsString) && (!usedReplacements.contains(charAsString) || allowDuplicates)) {
|
||||
usedReplacements.add(charAsString);
|
||||
result.add(charAsString);
|
||||
continue;
|
||||
}
|
||||
// reject any other character, as the ones we can deal with
|
||||
if (!this.reactMapping.getSingle().containsKey(charAsString)) {
|
||||
log.info("Cannot find mapping. Not replacing with emote.");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Shows the experience gain information of the top 10 users in the server, or if a page number is provided as a parameter, only the members which are on this page.
|
||||
@@ -69,18 +68,18 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
LeaderBoard leaderBoard = userExperienceService.findLeaderBoardData(server, page);
|
||||
LeaderBoardModel leaderBoardModel = (LeaderBoardModel) ContextConverter.slimFromCommandContext(commandContext, LeaderBoardModel.class);
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> futures = new ArrayList<>();
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard);
|
||||
futures.addAll(completableFutures);
|
||||
List<CompletableFuture> futures = new ArrayList<>();
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard);
|
||||
futures.add(completableFutures);
|
||||
log.info("Rendering leaderboard for page {} in server {} for user {}.", page, commandContext.getAuthor().getId(), commandContext.getGuild().getId());
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(aUserInAServer);
|
||||
CompletableFuture<LeaderBoardEntryModel> userRankFuture = converter.fromLeaderBoardEntry(userRank);
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> userRankFuture = converter.fromLeaderBoardEntry(Arrays.asList(userRank));
|
||||
futures.add(userRankFuture);
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenCompose(aVoid -> {
|
||||
List<LeaderBoardEntryModel> finalModels = completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
return FutureUtils.toSingleFuture(futures).thenCompose(aVoid -> {
|
||||
List<LeaderBoardEntryModel> finalModels = completableFutures.join();
|
||||
leaderBoardModel.setUserExperiences(finalModels);
|
||||
leaderBoardModel.setUserExecuting(userRankFuture.join());
|
||||
leaderBoardModel.setUserExecuting(userRankFuture.join().get(0));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(LEADER_BOARD_POST_EMBED_TEMPLATE, leaderBoardModel, commandContext.getGuild().getIdLong());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()));
|
||||
}).thenApply(aVoid -> CommandResult.fromIgnored());
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package dev.sheldan.abstracto.experience.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition;
|
||||
import dev.sheldan.abstracto.experience.model.template.LevelRole;
|
||||
import dev.sheldan.abstracto.experience.model.template.LevelRolesModel;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class LevelRoles extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleService experienceRoleService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
private static final String LEVEL_ROLES_TEMPLATE_KEY = "levelRoles_response";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
List<LevelRole> levelRoles = experienceRoleService.loadLevelRoleConfigForServer(server);
|
||||
levelRoles = levelRoles.stream().sorted(Comparator.comparingInt(LevelRole::getLevel).reversed()).collect(Collectors.toList());
|
||||
LevelRolesModel model = LevelRolesModel
|
||||
.builder()
|
||||
.levelRoles(levelRoles)
|
||||
.build();
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(LEVEL_ROLES_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("levelRoles")
|
||||
.module(ExperienceModuleDefinition.EXPERIENCE)
|
||||
.async(true)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ExperienceFeatureDefinition.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
@@ -24,11 +23,13 @@ import dev.sheldan.abstracto.experience.service.management.UserExperienceManagem
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -66,12 +67,17 @@ public class Rank extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
RankModel rankModel = (RankModel) ContextConverter.slimFromCommandContext(commandContext, RankModel.class);
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Member parameter = !parameters.isEmpty() ? (Member) parameters.get(0) : commandContext.getAuthor();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(parameter);
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(aUserInAServer);
|
||||
CompletableFuture<LeaderBoardEntryModel> future = converter.fromLeaderBoardEntry(userRank);
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> future = converter.fromLeaderBoardEntry(Arrays.asList(userRank));
|
||||
RankModel rankModel = RankModel
|
||||
.builder()
|
||||
.member(parameter)
|
||||
.build();
|
||||
return future.thenCompose(leaderBoardEntryModel ->
|
||||
self.renderAndSendRank(commandContext, rankModel, leaderBoardEntryModel)
|
||||
self.renderAndSendRank(commandContext, rankModel, leaderBoardEntryModel.get(0))
|
||||
).thenApply(result -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
@@ -89,6 +95,7 @@ public class Rank extends AbstractConditionableCommand {
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("member").templated(true).type(Member.class).optional(true).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("rank")
|
||||
|
||||
@@ -10,12 +10,16 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition;
|
||||
import dev.sheldan.abstracto.experience.exception.ExperienceRoleNotFoundException;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
@@ -31,13 +35,20 @@ public class UnSetExpRole extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleManagementService experienceRoleManagementService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
ARole role = (ARole) commandContext.getParameters().getParameters().get(0);
|
||||
ARole actualRole = roleManagementService.findRole(role.getId());
|
||||
// do not check for the existence of the role, because if the role was deleted, users should be able
|
||||
// to get rid of it in the configuration
|
||||
return experienceRoleService.unsetRole(actualRole, commandContext.getChannel().getIdLong())
|
||||
Optional<AExperienceRole> experienceRole = experienceRoleManagementService.getRoleInServerOptional(actualRole);
|
||||
if(!experienceRole.isPresent()) {
|
||||
throw new ExperienceRoleNotFoundException();
|
||||
}
|
||||
return experienceRoleService.unsetRoles(actualRole, commandContext.getChannel().getIdLong())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.sheldan.abstracto.experience.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoardEntry;
|
||||
@@ -11,11 +10,14 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Converter used to convert from {@link LeaderBoard leaderBoard} to a list of {@link LeaderBoardEntryModel leaderBoardEntryModels}
|
||||
@@ -40,40 +42,36 @@ public class LeaderBoardModelConverter {
|
||||
* @return The list of {@link LeaderBoardEntryModel leaderboarEntryModels} which contain the fully fledged information provided to the
|
||||
* leader board template
|
||||
*/
|
||||
public List<CompletableFuture<LeaderBoardEntryModel>> fromLeaderBoard(LeaderBoard leaderBoard) {
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> models = new ArrayList<>();
|
||||
public CompletableFuture<List<LeaderBoardEntryModel>> fromLeaderBoard(LeaderBoard leaderBoard) {
|
||||
log.debug("Converting {} entries to a list of leaderboard entries.", leaderBoard.getEntries().size());
|
||||
leaderBoard.getEntries().forEach(leaderBoardEntry -> {
|
||||
CompletableFuture<LeaderBoardEntryModel> entry = fromLeaderBoardEntry(leaderBoardEntry);
|
||||
models.add(entry);
|
||||
return fromLeaderBoardEntry(leaderBoard.getEntries());
|
||||
}
|
||||
|
||||
public CompletableFuture<List<LeaderBoardEntryModel>> fromLeaderBoardEntry(List<LeaderBoardEntry> leaderBoardEntries) {
|
||||
List<Long> userIds = new ArrayList<>();
|
||||
Long serverId = leaderBoardEntries.get(0).getExperience().getServer().getId();
|
||||
Map<Long, LeaderBoardEntryModel> models = leaderBoardEntries
|
||||
.stream()
|
||||
.map(leaderBoardEntry -> {
|
||||
AUserExperience experience = leaderBoardEntry.getExperience();
|
||||
Long userId = experience.getUser().getUserReference().getId();
|
||||
userIds.add(userId);
|
||||
return LeaderBoardEntryModel
|
||||
.builder()
|
||||
.userId(userId)
|
||||
.experience(experience.getExperience())
|
||||
.messageCount(experience.getMessageCount())
|
||||
.level(experience.getLevelOrDefault())
|
||||
.rank(leaderBoardEntry.getRank())
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toMap(LeaderBoardEntryModel::getUserId, Function.identity()));
|
||||
return memberService.getMembersInServerAsync(serverId, userIds).thenApply(members -> {
|
||||
members.forEach(member -> models.get(member.getIdLong()).setMember(member));
|
||||
return new ArrayList<>(models.values())
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(LeaderBoardEntryModel::getRank)).
|
||||
collect(Collectors.toList());
|
||||
});
|
||||
return models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link LeaderBoardEntry entry} to a {@link LeaderBoardEntryModel model}, which provides a reference to the
|
||||
* {@link Member member} object of the given {@link AUserInAServer user} for convenience in the template
|
||||
* @param leaderBoardEntry The {@link LeaderBoardEntry entry} to be converted
|
||||
* @return The {@link LeaderBoardEntryModel model} accompanied with the {@link Member member} reference, might be null, if the
|
||||
* user left the guild
|
||||
*/
|
||||
public CompletableFuture<LeaderBoardEntryModel> fromLeaderBoardEntry(LeaderBoardEntry leaderBoardEntry) {
|
||||
AUserInAServer entryUser = leaderBoardEntry.getExperience().getUser();
|
||||
Long userInServerId = leaderBoardEntry.getExperience().getUser().getUserInServerId();
|
||||
Integer rank = leaderBoardEntry.getRank();
|
||||
return memberService.getMemberInServerAsync(entryUser.getServerReference().getId(), entryUser.getUserReference().getId())
|
||||
.thenApply(member -> self.buildLeaderBoardModel(userInServerId, member, rank))
|
||||
.exceptionally(throwable -> self.buildLeaderBoardModel(userInServerId, null, rank));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public LeaderBoardEntryModel buildLeaderBoardModel(Long userInServerId, Member member, Integer rank) {
|
||||
AUserExperience experience = userExperienceManagementService.findByUserInServerId(userInServerId);
|
||||
return LeaderBoardEntryModel
|
||||
.builder()
|
||||
.experience(experience)
|
||||
.member(member)
|
||||
.rank(rank)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,16 @@ public class ExperienceTrackerListener implements AsyncMessageReceivedListener {
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||
Message message = model.getMessage();
|
||||
if(!message.isFromGuild() || message.isWebhookMessage() || message.getType().isSystem()) {
|
||||
if(!message.isFromGuild() || message.isWebhookMessage() || message.getType().isSystem() || message.getAuthor().isBot()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
if(userExperienceService.experienceGainEnabledInChannel(message.getChannel())) {
|
||||
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(model.getServerId(), model.getMessage().getAuthor().getIdLong());
|
||||
userExperienceService.addExperience(cause);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
} else {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(model.getServerId(), model.getMessage().getAuthor().getIdLong());
|
||||
userExperienceService.addExperience(cause);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.models.property.SystemConfigProperty;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultConfigManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.*;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatureConfig;
|
||||
@@ -26,6 +20,7 @@ import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -82,6 +77,9 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private DefaultConfigManagementService defaultConfigManagementService;
|
||||
|
||||
@@ -94,24 +92,26 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
try {
|
||||
Long minute = Instant.now().getEpochSecond() / 60;
|
||||
Map<Long, List<ServerExperience>> runtimeExperience = runTimeExperienceService.getRuntimeExperience();
|
||||
Long serverId = userInAServer.getServerReference().getId();
|
||||
Long userInServerId = userInAServer.getUserInServerId();
|
||||
if(runtimeExperience.containsKey(minute)) {
|
||||
log.debug("Minute {} already tracked, adding user {} in server {}.",
|
||||
minute, userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
|
||||
minute, userInAServer.getUserReference().getId(), serverId);
|
||||
List<ServerExperience> existing = runtimeExperience.get(minute);
|
||||
for (ServerExperience server : existing) {
|
||||
if (server.getServerId().equals(userInAServer.getServerReference().getId()) && server.getUserInServerIds().stream().noneMatch(userInAServer1 -> userInAServer.getUserInServerId().equals(userInAServer1))) {
|
||||
server.getUserInServerIds().add(userInAServer.getUserInServerId());
|
||||
if (server.getServerId().equals(serverId) && server.getUserInServerIds().stream().noneMatch(userInServerId::equals)) {
|
||||
server.getUserInServerIds().add(userInServerId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
log.debug("Minute {} did not exist yet. Creating new entry for user {} in server {}.", minute, userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
|
||||
log.debug("Minute {} did not exist yet. Creating new entry for user {} in server {}.", minute, userInAServer.getUserReference().getId(), serverId);
|
||||
ServerExperience serverExperience = ServerExperience
|
||||
.builder()
|
||||
.serverId(userInAServer.getServerReference().getId())
|
||||
.serverId(serverId)
|
||||
.build();
|
||||
serverExperience.getUserInServerIds().add(userInAServer.getUserInServerId());
|
||||
serverExperience.getUserInServerIds().add(userInServerId);
|
||||
runtimeExperience.put(minute, new ArrayList<>(Arrays.asList(serverExperience)));
|
||||
}
|
||||
} finally {
|
||||
@@ -180,7 +180,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
SystemConfigProperty defaultMinExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MIN_EXP_KEY);
|
||||
SystemConfigProperty defaultMaxExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MAX_EXP_KEY);
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
log.info("Handling {} experience for server {}", memberFutures.size(), serverId);
|
||||
int minExp = configService.getLongValue(ExperienceFeatureConfig.MIN_EXP_KEY, serverId, defaultMinExp.getLongValue()).intValue();
|
||||
int maxExp = configService.getLongValue(ExperienceFeatureConfig.MAX_EXP_KEY, serverId, defaultMaxExp.getLongValue()).intValue();
|
||||
Double multiplier = configService.getDoubleValue(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId, defaultExpMultiplier.getDoubleValue());
|
||||
@@ -190,18 +189,21 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(server);
|
||||
List<ARole> disabledRoles = disabledExpRoles.stream().map(ADisabledExpRole::getRole).collect(Collectors.toList());
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
log.info("Handling {} experiences for server {}. Using {} roles.", memberFutures.size(), serverId, roles.size());
|
||||
memberFutures.forEach(future -> {
|
||||
if(!future.isCompletedExceptionally()) {
|
||||
Integer gainedExperience = iterator.next();
|
||||
gainedExperience = (int) Math.floor(gainedExperience * multiplier);
|
||||
Member member = future.join();
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
Long userInServerId = userInAServer.getUserInServerId();
|
||||
if(!roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
log.debug("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
log.debug("Handling {}. The user might gain {}.", userInServerId, gainedExperience);
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
|
||||
if(aUserExperienceOptional.isPresent()) {
|
||||
AUserExperience aUserExperience = aUserExperienceOptional.get();
|
||||
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
|
||||
log.debug("User {} will gain experience.", userInServerId);
|
||||
Long newExperienceCount = aUserExperience.getExperience() + gainedExperience.longValue();
|
||||
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
|
||||
CompletableFuture<RoleCalculationResult> resultFuture = updateUserRole(aUserExperience, roles, newLevel.getLevel());
|
||||
@@ -240,7 +242,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
futures.add(resultFuture);
|
||||
}
|
||||
} else {
|
||||
log.info("User {} has a role which makes the user unable to gain experience.", userInAServer.getUserInServerId());
|
||||
log.debug("User {} has a role which makes the user unable to gain experience.", userInAServer.getUserInServerId());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -296,7 +298,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
AUserExperience userExperience;
|
||||
if(experienceGainResult.isCreateUserExperience()) {
|
||||
userExperience = userExperienceManagementService.createUserInServer(user);
|
||||
log.info("Creating new experience user {}", experienceGainResult.getUserInServerId());
|
||||
log.info("Creating new experience user for user in server {}.", experienceGainResult.getUserInServerId());
|
||||
} else {
|
||||
userExperience = userExperienceManagementService.findByUserInServerId(experienceGainResult.getUserInServerId());
|
||||
}
|
||||
@@ -346,7 +348,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
log.debug("User {} in server {} does not have an experience role, according to new calculation.",
|
||||
user.getUserReference().getId(), serverId);
|
||||
// if the user has a experience role currently, remove it
|
||||
if(!currentlyHasNoExperienceRole){
|
||||
if(!currentlyHasNoExperienceRole && !userExperience.getCurrentExperienceRole().getRole().getDeleted()){
|
||||
return roleService.removeRoleFromUserFuture(user, userExperience.getCurrentExperienceRole().getRole())
|
||||
.thenApply(returnNullRole);
|
||||
}
|
||||
@@ -373,16 +375,17 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
// if the roles changed or
|
||||
// the user does not have the new target role already
|
||||
// the user still has the old role
|
||||
if((!userHasRoleAlready || userHasOldRole)) {
|
||||
log.info("User {} in server {} gets a new role {} because of experience.", userId, serverId, roleId);
|
||||
if(!userHasRoleAlready || userHasOldRole) {
|
||||
CompletableFuture<Void> removalFuture;
|
||||
if(userHasOldRole && rolesChanged) {
|
||||
log.info("User {} in server {} loses experience role {}.", userId, serverId, oldUserExperienceRoleId);
|
||||
removalFuture = roleService.removeRoleFromMemberAsync(member, oldUserExperienceRoleId);
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture<Void> addRoleFuture;
|
||||
if(!userHasRoleAlready) {
|
||||
log.info("User {} in server {} gets a new role {} because of experience.", userId, serverId, roleId);
|
||||
addRoleFuture = roleService.addRoleToMemberFuture(member, roleId);
|
||||
} else {
|
||||
addRoleFuture = CompletableFuture.completedFuture(null);
|
||||
@@ -403,7 +406,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
for (int i = 0; i < aUserExperiences.size(); i++) {
|
||||
AUserExperience userExperience = aUserExperiences.get(i);
|
||||
log.debug("Synchronizing {} out of {}", i, aUserExperiences.size());
|
||||
log.info("Synchronizing {} out of {}. User in Server {}.", i, aUserExperiences.size(), userExperience.getUser().getUserInServerId());
|
||||
results.add(updateUserRole(userExperience, roles, userExperience.getCurrentLevel().getLevel()));
|
||||
}
|
||||
return results;
|
||||
@@ -424,7 +427,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
|
||||
/**
|
||||
* Updates the actually stored experience roles in the database
|
||||
* @param results The list of {@link RoleCalculationResult} which should be applied
|
||||
* @param results The list of {@link RoleCalculationResult results} which should be applied
|
||||
*/
|
||||
@Transactional
|
||||
public void syncRolesInStorage(List<RoleCalculationResult> results) {
|
||||
@@ -452,6 +455,33 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean experienceGainEnabledInChannel(MessageChannel messageChannel) {
|
||||
AChannel channel = channelManagementService.loadChannel(messageChannel.getIdLong());
|
||||
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, EXPERIENCE_GAIN_CHANNEL_GROUP_KEY);
|
||||
if(!channelGroups.isEmpty()) {
|
||||
return channelGroups.stream().noneMatch(AChannelGroup::getEnabled);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserExperience createUserExperienceForUser(AUserInAServer aUserInAServer, Long experience, Long messageCount) {
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
return createUserExperienceForUser(aUserInAServer, experience, messageCount, levels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserExperience createUserExperienceForUser(AUserInAServer aUserInAServer, Long experience, Long messageCount, List<AExperienceLevel> levels) {
|
||||
AExperienceLevel level = calculateLevel(levels, experience);
|
||||
AUserExperience userExperience = userExperienceManagementService.createUserInServer(aUserInAServer);
|
||||
userExperience.setCurrentLevel(level);
|
||||
userExperience.setExperience(experience);
|
||||
userExperience.setMessageCount(messageCount);
|
||||
return userExperience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFutureList<RoleCalculationResult> executeActionOnUserExperiencesWithFeedBack(List<AUserExperience> experiences, AChannel channel, Function<AUserExperience, CompletableFuture<RoleCalculationResult>> toExecute) {
|
||||
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
|
||||
@@ -461,12 +491,13 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
int interval = Math.min(Math.max(experiences.size() / 10, 1), 100);
|
||||
for (int i = 0; i < experiences.size(); i++) {
|
||||
if((i % interval) == 1) {
|
||||
log.debug("Updating feedback message with new index {} out of {}", i, experiences.size());
|
||||
log.info("Updating feedback message with new index {} out of {}.", i, experiences.size());
|
||||
status = getUserSyncStatusUpdateModel(i, experiences.size(), serverId);
|
||||
messageService.updateStatusMessage(channel, statusMessage.getIdLong(), status);
|
||||
}
|
||||
futures.add(toExecute.apply(experiences.get(i)));
|
||||
log.debug("Synchronizing {} out of {}", i, experiences.size());
|
||||
AUserExperience userExperience = experiences.get(i);
|
||||
futures.add(toExecute.apply(userExperience));
|
||||
log.debug("Synchronizing {} out of {}. User in server ID {}.", i, experiences.size(), userExperience.getUser().getUserInServerId());
|
||||
}
|
||||
status = getUserSyncStatusUpdateModel(experiences.size(), experiences.size(), serverId);
|
||||
messageService.updateStatusMessage(channel, statusMessage.getIdLong(), status);
|
||||
@@ -483,8 +514,8 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
|
||||
@Override
|
||||
public void enableExperienceForUser(AUserInAServer userInAServer) {
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
log.info("Enabling experience gain for user {} in server {}.", userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
userExperience.setExperienceGainDisabled(false);
|
||||
}
|
||||
|
||||
@@ -503,7 +534,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
@Override
|
||||
public CompletableFuture<RoleCalculationResult> syncForSingleUser(AUserExperience userExperience) {
|
||||
AUserInAServer user = userExperience.getUser();
|
||||
log.info("Synchronizing for user {} in server {}", user.getUserReference().getId(), user.getServerReference().getId());
|
||||
log.info("Synchronizing for user {} in server {}.", user.getUserReference().getId(), user.getServerReference().getId());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(user.getServerReference());
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
return updateUserRole(userExperience, roles, userExperience.getLevelOrDefault());
|
||||
@@ -517,12 +548,13 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
page--;
|
||||
int pageSize = 10;
|
||||
log.debug("Loading leaderboard page {} for server {}.", page, server.getId());
|
||||
List<AUserExperience> experiences = userExperienceManagementService.findLeaderBoardUsersPaginated(server, page * pageSize, (page + 1) * pageSize);
|
||||
List<AUserExperience> experiences = userExperienceManagementService.findLeaderBoardUsersPaginated(server, page, pageSize);
|
||||
List<LeaderBoardEntry> entries = new ArrayList<>();
|
||||
log.debug("Found {} experiences.", experiences.size());
|
||||
int pageOffset = page * pageSize;
|
||||
for (int i = 0; i < experiences.size(); i++) {
|
||||
AUserExperience userExperience = experiences.get(i);
|
||||
entries.add(LeaderBoardEntry.builder().experience(userExperience).rank((page * pageSize) + i + 1).build());
|
||||
entries.add(LeaderBoardEntry.builder().experience(userExperience).rank(pageOffset + i + 1).build());
|
||||
}
|
||||
return LeaderBoard.builder().entries(entries).build();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ExperienceLevelServiceBean implements ExperienceLevelService {
|
||||
|
||||
@Override
|
||||
public Long calculateExperienceToNextLevel(Integer level, Long currentExperience) {
|
||||
AExperienceLevel nextLevel = experienceLevelManagementService.getLevel(level + 1)
|
||||
AExperienceLevel nextLevel = experienceLevelManagementService.getLevelOptional(level + 1)
|
||||
.orElseThrow(() -> new AbstractoRunTimeException(String.format("Could not find level %s", level)));
|
||||
return nextLevel.getExperienceNeeded() - currentExperience;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.experience.service;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
@@ -10,6 +11,7 @@ import dev.sheldan.abstracto.experience.model.RoleCalculationResult;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.model.template.LevelRole;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -18,9 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -46,6 +46,9 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
/**
|
||||
* UnSets the current configuration for the passed level, and sets the {@link ARole} to be used for this level
|
||||
* in the given {@link AServer}
|
||||
@@ -55,14 +58,43 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Override
|
||||
public CompletableFuture<Void> setRoleToLevel(Role role, Integer level, Long channelId) {
|
||||
Long roleId = role.getIdLong();
|
||||
ARole aRole = roleManagementService.findRole(roleId);
|
||||
return unsetRole(aRole, channelId).thenAccept(aVoid ->
|
||||
ARole aRoleToSet = roleManagementService.findRole(roleId);
|
||||
List<AExperienceRole> experienceRoles = getExperienceRolesAtLevel(level, aRoleToSet.getServer());
|
||||
List<ARole> rolesToUnset = experienceRoles.stream().map(AExperienceRole::getRole).collect(Collectors.toList());
|
||||
if(rolesToUnset.size() == 1 && rolesToUnset.contains(aRoleToSet)) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
if(!rolesToUnset.contains(aRoleToSet)) {
|
||||
rolesToUnset.add(aRoleToSet);
|
||||
}
|
||||
AExperienceLevel experienceLevel;
|
||||
if(!experienceRoles.isEmpty()) {
|
||||
experienceLevel = experienceRoles.get(0).getLevel();
|
||||
} else {
|
||||
experienceLevel = experienceLevelService.getLevel(level);
|
||||
}
|
||||
AExperienceRole newExperienceRole = experienceRoleManagementService.setLevelToRole(experienceLevel, aRoleToSet);
|
||||
Long newlyCreatedExperienceRoleId = newExperienceRole.getId();
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
unsetRoles(rolesToUnset, channelId, newExperienceRole).thenAccept(aVoid ->
|
||||
self.unsetRoleInDb(level, roleId)
|
||||
);
|
||||
).thenAccept(unused -> future.complete(null)).exceptionally(throwable -> {
|
||||
self.deleteExperienceRoleViaId(newlyCreatedExperienceRoleId);
|
||||
future.completeExceptionally(throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteExperienceRoleViaId(Long newlyCreatedExperienceRoleId) {
|
||||
AExperienceRole reLoadedRole = experienceRoleManagementService.getExperienceRoleById(newlyCreatedExperienceRoleId);
|
||||
experienceRoleManagementService.unsetRole(reLoadedRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all previous defined {@link AExperienceRole experienceRoles} from the given leve and sets the {@link ARole}
|
||||
* Removes all previous defined {@link AExperienceRole experienceRoles} from the given level and sets the {@link ARole}
|
||||
* (defined by its ID) to the level.
|
||||
* @param level The level which the {@link ARole role} should be set to
|
||||
* @param roleId The ID of the {@link Role} which should have its level set
|
||||
@@ -70,9 +102,9 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Transactional
|
||||
public void unsetRoleInDb(Integer level, Long roleId) {
|
||||
log.info("Unsetting role {} from level {}.", roleId, level);
|
||||
AExperienceLevel experienceLevel = experienceLevelService.getLevel(level).orElseThrow(() -> new IllegalArgumentException(String.format("Could not find level %s", level)));
|
||||
AExperienceLevel experienceLevel = experienceLevelService.getLevelOptional(level).orElseThrow(() -> new IllegalArgumentException(String.format("Could not find level %s", level)));
|
||||
ARole loadedRole = roleManagementService.findRole(roleId);
|
||||
experienceRoleManagementService.removeAllRoleAssignmentsForLevelInServer(experienceLevel, loadedRole.getServer());
|
||||
experienceRoleManagementService.removeAllRoleAssignmentsForLevelInServerExceptRole(experienceLevel, loadedRole.getServer(), loadedRole);
|
||||
experienceRoleManagementService.setLevelToRole(experienceLevel, loadedRole);
|
||||
}
|
||||
|
||||
@@ -83,31 +115,54 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
* configuration
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> unsetRole(ARole role, Long feedbackChannelId) {
|
||||
AChannel channel = channelManagementService.loadChannel(feedbackChannelId);
|
||||
Optional<AExperienceRole> roleInServerOptional = experienceRoleManagementService.getRoleInServerOptional(role);
|
||||
if(roleInServerOptional.isPresent()) {
|
||||
AExperienceRole roleInServer = roleInServerOptional.get();
|
||||
if(!roleInServer.getUsers().isEmpty()) {
|
||||
log.info("Recalculating the roles for {} users, because their current role was removed from experience tracking.", roleInServer.getUsers().size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(role.getServer());
|
||||
roles.removeIf(role1 -> role1.getId().equals(roleInServer.getId()));
|
||||
roles.sort(Comparator.comparing(innerRole -> innerRole.getLevel().getLevel()));
|
||||
Long roleId = role.getId();
|
||||
CompletableFutureList<RoleCalculationResult> calculationResults = userExperienceService.executeActionOnUserExperiencesWithFeedBack(roleInServer.getUsers(), channel,
|
||||
(AUserExperience ex) -> userExperienceService.updateUserRole(ex, roles, ex.getLevelOrDefault()));
|
||||
return calculationResults.getMainFuture().thenAccept(aVoid ->
|
||||
self.persistData(calculationResults, roleId)
|
||||
);
|
||||
} else {
|
||||
log.info("Roles does not have any active users, no need to remove them.");
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
} else {
|
||||
log.info("Experience role is not define in server - skipping unset.");
|
||||
public CompletableFuture<Void> unsetRoles(ARole role, Long feedbackChannelId) {
|
||||
return unsetRoles(Arrays.asList(role), feedbackChannelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceRole> getExperienceRolesAtLevel(Integer level, AServer server) {
|
||||
AExperienceLevel levelObj = experienceLevelService.getLevel(level);
|
||||
return experienceRoleManagementService.getExperienceRolesAtLevelInServer(levelObj, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> unsetRoles(List<ARole> rolesToUnset, Long feedbackChannelId) {
|
||||
return unsetRoles(rolesToUnset, feedbackChannelId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> unsetRoles(List<ARole> rolesToUnset, Long feedbackChannelId, AExperienceRole toAdd) {
|
||||
if(rolesToUnset.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
AServer server = rolesToUnset.get(0).getServer();
|
||||
AChannel channel = channelManagementService.loadChannel(feedbackChannelId);
|
||||
List<AExperienceRole> experienceRolesNecessaryToRemove = new ArrayList<>();
|
||||
List<AUserExperience> usersToUpdate = new ArrayList<>();
|
||||
rolesToUnset.forEach(role -> {
|
||||
Optional<AExperienceRole> roleInServerOptional = experienceRoleManagementService.getRoleInServerOptional(role);
|
||||
if(roleInServerOptional.isPresent()) {
|
||||
AExperienceRole experienceRole = roleInServerOptional.get();
|
||||
experienceRolesNecessaryToRemove.add(experienceRole);
|
||||
usersToUpdate.addAll(experienceRole.getUsers());
|
||||
} else {
|
||||
log.info("Experience role {} is not defined in server {} - skipping unset.", role.getId(), server.getId());
|
||||
}
|
||||
});
|
||||
log.info("Recalculating the roles for {} users, because their current role was removed from experience tracking.", usersToUpdate.size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
roles.removeIf(role1 -> experienceRolesNecessaryToRemove.stream().anyMatch(aExperienceRole -> aExperienceRole.getId().equals(role1.getId())));
|
||||
if(toAdd != null) {
|
||||
roles.add(toAdd);
|
||||
}
|
||||
roles.sort(Comparator.comparing(innerRole -> innerRole.getLevel().getLevel()));
|
||||
List<Long> roleIds = experienceRolesNecessaryToRemove.stream().map(AExperienceRole::getId).collect(Collectors.toList());
|
||||
if(toAdd != null) {
|
||||
roleIds.removeIf(aLong -> aLong.equals(toAdd.getRole().getId()));
|
||||
}
|
||||
CompletableFutureList<RoleCalculationResult> calculationResults = userExperienceService.executeActionOnUserExperiencesWithFeedBack(usersToUpdate, channel,
|
||||
(AUserExperience ex) -> userExperienceService.updateUserRole(ex, roles, ex.getLevelOrDefault()));
|
||||
return calculationResults.getMainFuture().thenAccept(aVoid -> self.persistData(calculationResults, roleIds));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,13 +171,15 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
* have to remove the existing {@link AExperienceRole experienceRole}
|
||||
* @param results A list of {@link CompletableFuture futures} which each contain a {@link RoleCalculationResult result}, for the members who got
|
||||
* their {@link AExperienceRole experienceRole} removed
|
||||
* @param roleId The ID of the {@link AExperienceRole experienceRole} which was removed from the experience roles
|
||||
* @param roleIds The IDs of the {@link AExperienceRole experienceRoles} which were removed from the experience roles
|
||||
*/
|
||||
@Transactional
|
||||
public void persistData(CompletableFutureList<RoleCalculationResult> results, Long roleId) {
|
||||
log.info("Persisting {} role calculation results after changing the role {}.", results.getFutures().size(), roleId);
|
||||
AExperienceRole roleInServer = experienceRoleManagementService.getExperienceRoleById(roleId);
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
public void persistData(CompletableFutureList<RoleCalculationResult> results, List<Long> roleIds) {
|
||||
log.info("Persisting {} role calculation results.", results.getFutures().size());
|
||||
roleIds.forEach(roleId -> {
|
||||
log.info("Deleting experience role {}.", roleId);
|
||||
deleteExperienceRoleViaId(roleId);
|
||||
});
|
||||
userExperienceService.syncRolesInStorage(results.getObjects());
|
||||
}
|
||||
|
||||
@@ -153,4 +210,21 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
return aExperienceRole != null ? aExperienceRole.getLevel() : AExperienceLevel.builder().level(200).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LevelRole> loadLevelRoleConfigForServer(AServer server) {
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
List<LevelRole> levelRoles = new ArrayList<>();
|
||||
roles.forEach(aExperienceRole -> {
|
||||
Role role = roleService.getRoleFromGuild(aExperienceRole.getRole());
|
||||
LevelRole levelRole = LevelRole
|
||||
.builder()
|
||||
.role(role)
|
||||
.roleId(aExperienceRole.getId())
|
||||
.level(aExperienceRole.getLevel().getLevel())
|
||||
.build();
|
||||
levelRoles.add(levelRole);
|
||||
});
|
||||
return levelRoles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.repository.ExperienceLevelRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -9,7 +10,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class ExperienceLevelManagementServiceBean implements ExperienceLevelManagementService {
|
||||
public class ExperienceLevelManagementServiceBean implements ExperienceLevelManagementService {
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelRepository experienceLevelRepository;
|
||||
@@ -30,10 +31,15 @@ public class ExperienceLevelManagementServiceBean implements ExperienceLevelM
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AExperienceLevel> getLevel(Integer level) {
|
||||
public Optional<AExperienceLevel> getLevelOptional(Integer level) {
|
||||
return experienceLevelRepository.findById(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceLevel getLevel(Integer level) {
|
||||
return getLevelOptional(level).orElseThrow(() -> new AbstractoRunTimeException("Level not found."));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceLevel> getLevelConfig() {
|
||||
return experienceLevelRepository.findAll();
|
||||
|
||||
@@ -30,10 +30,14 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
* @param server The server in which this should happen
|
||||
*/
|
||||
@Override
|
||||
public void removeAllRoleAssignmentsForLevelInServer(AExperienceLevel level, AServer server) {
|
||||
public void removeAllRoleAssignmentsForLevelInServerExceptRole(AExperienceLevel level, AServer server, ARole role) {
|
||||
List<AExperienceRole> existingExperienceRoles = experienceRoleRepository.findByLevelAndRoleServer(level, server);
|
||||
log.info("Removing all role assignments ({}) for level {} in server {}.", existingExperienceRoles.size(), level.getLevel(), server.getId());
|
||||
existingExperienceRoles.forEach(existingRole -> experienceRoleRepository.delete(existingRole));
|
||||
existingExperienceRoles.forEach(existingRole -> {
|
||||
if(!existingRole.getRole().getId().equals(role.getId())) {
|
||||
experienceRoleRepository.delete(existingRole);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,4 +101,9 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
}
|
||||
return experienceRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceRole> getExperienceRolesAtLevelInServer(AExperienceLevel level, AServer server) {
|
||||
return experienceRoleRepository.findByLevelAndRoleServer(level, server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
|
||||
@Override
|
||||
public AUserExperience createUserInServer(AUserInAServer aUserInAServer) {
|
||||
log.info("Creating user experience for user {} in server {}.", aUserInAServer.getUserReference().getId(),aUserInAServer.getServerReference().getId());
|
||||
AExperienceLevel startingLevel = experienceLevelManagementService.getLevel(0).orElseThrow(() -> new AbstractoRunTimeException(String.format("Could not find level %s", 0)));
|
||||
AExperienceLevel startingLevel = experienceLevelManagementService.getLevelOptional(0).orElseThrow(() -> new AbstractoRunTimeException(String.format("Could not find level %s", 0)));
|
||||
return AUserExperience
|
||||
.builder()
|
||||
.experience(0L)
|
||||
@@ -64,8 +64,8 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AUserExperience> findLeaderBoardUsersPaginated(AServer aServer, Integer start, Integer end) {
|
||||
return repository.findTop10ByUser_ServerReferenceOrderByExperienceDesc(aServer, PageRequest.of(start, end));
|
||||
public List<AUserExperience> findLeaderBoardUsersPaginated(AServer aServer, Integer page, Integer size) {
|
||||
return repository.findTop10ByUser_ServerReferenceOrderByExperienceDesc(aServer, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="experience_gain_channel_group_type-insertion">
|
||||
<insert tableName="channel_group_type">
|
||||
<column name="group_type_key" value="experienceGain"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -64,6 +64,11 @@
|
||||
<column name="module_id" valueComputed="${experienceModule}"/>
|
||||
<column name="feature_id" valueComputed="${experienceFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="levelRoles"/>
|
||||
<column name="module_id" valueComputed="${experienceModule}"/>
|
||||
<column name="feature_id" valueComputed="${experienceFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -11,4 +11,5 @@
|
||||
<include file="module.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="experience_job.xml" relativeToChangelogFile="true"/>
|
||||
<include file="channel_group_types.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -74,11 +74,11 @@ public class LeaderBoardCommandTest {
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(userInServerManagementService.loadOrCreateUser(context.getAuthor())).thenReturn(userInAServer);
|
||||
when(userExperienceService.findLeaderBoardData(server, expectedPage)).thenReturn(leaderBoard);
|
||||
when(converter.fromLeaderBoard(leaderBoard)).thenReturn(new ArrayList<>());
|
||||
when(converter.fromLeaderBoard(leaderBoard)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
LeaderBoardEntry executingUserRank = Mockito.mock(LeaderBoardEntry.class);
|
||||
when(userExperienceService.getRankOfUserInServer(userInAServer)).thenReturn(executingUserRank);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
when(converter.fromLeaderBoardEntry(executingUserRank)).thenReturn(CompletableFuture.completedFuture(leaderBoardEntryModel));
|
||||
when(converter.fromLeaderBoardEntry(Arrays.asList(executingUserRank))).thenReturn(CompletableFuture.completedFuture(Arrays.asList(leaderBoardEntryModel)));
|
||||
MessageToSend messageToSend = Mockito.mock(MessageToSend.class);
|
||||
when(templateService.renderEmbedTemplate(eq(LeaderBoardCommand.LEADER_BOARD_POST_EMBED_TEMPLATE), any(LeaderBoardModel.class), eq(SERVER_ID))).thenReturn(messageToSend);
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
|
||||
@@ -73,7 +73,7 @@ public class RankTest {
|
||||
when(userInServerManagementService.loadOrCreateUser(context.getAuthor())).thenReturn(aUserInAServer);
|
||||
when(userExperienceService.getRankOfUserInServer(aUserInAServer)).thenReturn(leaderBoardEntry);
|
||||
LeaderBoardEntryModel leaderBoardEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
when(converter.fromLeaderBoardEntry(leaderBoardEntry)).thenReturn(CompletableFuture.completedFuture(leaderBoardEntryModel));
|
||||
when(converter.fromLeaderBoardEntry(Arrays.asList(leaderBoardEntry))).thenReturn(CompletableFuture.completedFuture(Arrays.asList(leaderBoardEntryModel)));
|
||||
when(self.renderAndSendRank(eq(context), any(RankModel.class), eq(leaderBoardEntryModel))).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
|
||||
@@ -6,7 +6,9 @@ import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandConfigValidator;
|
||||
import dev.sheldan.abstracto.core.test.command.CommandTestUtilities;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -15,6 +17,7 @@ import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -31,6 +34,9 @@ public class UnSetExpRoleTest {
|
||||
@Mock
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Mock
|
||||
private ExperienceRoleManagementService experienceRoleManagementService;
|
||||
|
||||
private static final Long CHANNEL_ID = 4L;
|
||||
|
||||
@Test
|
||||
@@ -41,7 +47,8 @@ public class UnSetExpRoleTest {
|
||||
when(context.getChannel().getIdLong()).thenReturn(CHANNEL_ID);
|
||||
ARole actualRole = Mockito.mock(ARole.class);
|
||||
when(roleManagementService.findRole(changedRole.getId())).thenReturn(actualRole);
|
||||
when(experienceRoleService.unsetRole(actualRole, CHANNEL_ID)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(experienceRoleManagementService.getRoleInServerOptional(actualRole)).thenReturn(Optional.of(Mockito.mock(AExperienceRole.class)));
|
||||
when(experienceRoleService.unsetRoles(actualRole, CHANNEL_ID)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<CommandResult> result = testUnit.executeAsync(context);
|
||||
CommandTestUtilities.checkSuccessfulCompletionAsync(result);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.model.template.LeaderBoardEntryModel;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.hibernate.event.spi.ClearEventListener;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -40,6 +42,9 @@ public class LeaderBoardModelConverterTest {
|
||||
private static final Long USER_ID_2 = 6L;
|
||||
private static final Long USER_IN_SERVER_ID = 7L;
|
||||
private static final Long USER_IN_SERVER_ID_2 = 8L;
|
||||
private static final Long EXPERIENCE = 9L;
|
||||
private static final Long MESSAGES = 10L;
|
||||
private static final Integer LEVEL = 54;
|
||||
|
||||
@Test
|
||||
public void testFromLeaderBoard() {
|
||||
@@ -47,49 +52,33 @@ public class LeaderBoardModelConverterTest {
|
||||
|
||||
LeaderBoardEntry entry = getEntry(firstRank, USER_ID, USER_IN_SERVER_ID);
|
||||
Integer secondRank = 2;
|
||||
LeaderBoardEntryModel firstEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
LeaderBoardEntryModel secondEntryModel = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
LeaderBoardEntry entry2 = getEntry(secondRank, USER_ID_2, USER_IN_SERVER_ID_2);
|
||||
List<LeaderBoardEntry> entries = Arrays.asList(entry, entry2);
|
||||
LeaderBoard leaderBoard = Mockito.mock(LeaderBoard.class);
|
||||
when(leaderBoard.getEntries()).thenReturn(entries);
|
||||
Member member = Mockito.mock(Member.class);
|
||||
when(memberService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(member));
|
||||
when(memberService.getMemberInServerAsync(SERVER_ID, USER_ID_2)).thenReturn(CompletableFuture.completedFuture(member));
|
||||
when(self.buildLeaderBoardModel(USER_IN_SERVER_ID, member, firstRank)).thenReturn(firstEntryModel);
|
||||
when(self.buildLeaderBoardModel(USER_IN_SERVER_ID_2, member, secondRank)).thenReturn(secondEntryModel);
|
||||
List<CompletableFuture<LeaderBoardEntryModel>> leaderBoardEntryModels = testUnit.fromLeaderBoard(leaderBoard);
|
||||
LeaderBoardEntryModel firstEntry = leaderBoardEntryModels.get(0).join();
|
||||
Assert.assertEquals(firstEntryModel, firstEntry);
|
||||
LeaderBoardEntryModel secondEntry = leaderBoardEntryModels.get(1).join();
|
||||
Assert.assertEquals(secondEntryModel, secondEntry);
|
||||
Assert.assertEquals(entries.size(), leaderBoardEntryModels.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromEntry() {
|
||||
Integer rank = 2;
|
||||
LeaderBoardEntry entry = getEntry(rank, USER_ID, USER_IN_SERVER_ID);
|
||||
Member member = Mockito.mock(Member.class);
|
||||
LeaderBoardEntryModel entryModelMock = Mockito.mock(LeaderBoardEntryModel.class);
|
||||
when(memberService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(member));
|
||||
when(self.buildLeaderBoardModel(USER_IN_SERVER_ID, member, rank)).thenReturn(entryModelMock);
|
||||
CompletableFuture<LeaderBoardEntryModel> leaderBoardEntryModel = testUnit.fromLeaderBoardEntry(entry);
|
||||
LeaderBoardEntryModel entryModel = leaderBoardEntryModel.join();
|
||||
Assert.assertEquals(entryModelMock, entryModel);
|
||||
when(member.getIdLong()).thenReturn(USER_ID);
|
||||
when(memberService.getMembersInServerAsync(SERVER_ID, Arrays.asList(USER_ID, USER_ID_2))).thenReturn(CompletableFuture.completedFuture(Arrays.asList(member)));
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> leaderBoardEntryModels = testUnit.fromLeaderBoard(leaderBoard);
|
||||
LeaderBoardEntryModel firstEntry = leaderBoardEntryModels.join().get(0);
|
||||
Assert.assertEquals(USER_ID, firstEntry.getUserId());
|
||||
LeaderBoardEntryModel secondEntry = leaderBoardEntryModels.join().get(1);
|
||||
Assert.assertEquals(USER_ID_2, secondEntry.getUserId());
|
||||
Assert.assertEquals(entries.size(), leaderBoardEntryModels.join().size());
|
||||
}
|
||||
|
||||
private LeaderBoardEntry getEntry(Integer rank, Long userId, Long userInServerId) {
|
||||
AUserExperience experience = Mockito.mock(AUserExperience.class);
|
||||
when(experience.getMessageCount()).thenReturn(MESSAGES);
|
||||
when(experience.getExperience()).thenReturn(EXPERIENCE);
|
||||
AUserInAServer userInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(experience.getUser()).thenReturn(userInAServer);
|
||||
AUser user = Mockito.mock(AUser.class);
|
||||
when(userInAServer.getUserReference()).thenReturn(user);
|
||||
when(userInAServer.getUserInServerId()).thenReturn(userInServerId);
|
||||
when(user.getId()).thenReturn(userId);
|
||||
AServer server = Mockito.mock(AServer.class);
|
||||
when(experience.getServer()).thenReturn(server);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(userInAServer.getServerReference()).thenReturn(server);
|
||||
LeaderBoardEntry entry = Mockito.mock(LeaderBoardEntry.class);
|
||||
when(entry.getRank()).thenReturn(rank);
|
||||
when(entry.getExperience()).thenReturn(experience);
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
import net.dv8tion.jda.api.entities.MessageType;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.junit.Test;
|
||||
@@ -43,10 +44,13 @@ public class ExperienceTrackerListenerTest {
|
||||
Message mockedMessage = Mockito.mock(Message.class);
|
||||
when(mockedMessage.isFromGuild()).thenReturn(true);
|
||||
when(mockedMessage.isWebhookMessage()).thenReturn(false);
|
||||
MessageChannel channel = Mockito.mock(MessageChannel.class);
|
||||
MessageType type = MessageType.DEFAULT;
|
||||
when(mockedMessage.getType()).thenReturn(type);
|
||||
when(userInServerManagementService.loadOrCreateUser(SERVER_ID, USER_ID)).thenReturn(userInAServer);
|
||||
when(model.getMessage()).thenReturn(mockedMessage);
|
||||
when(userExperienceService.experienceGainEnabledInChannel(channel)).thenReturn(true);
|
||||
when(mockedMessage.getChannel()).thenReturn(channel);
|
||||
when(model.getServerId()).thenReturn(SERVER_ID);
|
||||
when(mockedMessage.getAuthor()).thenReturn(user);
|
||||
when(user.getIdLong()).thenReturn(USER_ID);
|
||||
|
||||
@@ -409,7 +409,6 @@ public class AUserExperienceServiceBeanTest {
|
||||
setupDefaultConfig();
|
||||
setupLevelsAndRolesAndNoDisallowed();
|
||||
setExperienceRoleLevels();
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(userExperience.getExperienceGainDisabled()).thenReturn(true);
|
||||
|
||||
ArrayList<ExperienceGainResult> experienceResults = new ArrayList<>();
|
||||
@@ -760,7 +759,7 @@ public class AUserExperienceServiceBeanTest {
|
||||
when(userExperience2.getExperience()).thenReturn(MID_EXP);
|
||||
when(userExperience2.getCurrentLevel()).thenReturn(level1);
|
||||
when(userExperience2.getUser()).thenReturn(aUserInAServer2);
|
||||
when(userExperienceManagementService.findLeaderBoardUsersPaginated(server, (page - 1) * pageSize, page * pageSize)).thenReturn(experiences);
|
||||
when(userExperienceManagementService.findLeaderBoardUsersPaginated(server, page - 1, pageSize)).thenReturn(experiences);
|
||||
LeaderBoard leaderBoardData = testUnit.findLeaderBoardData(server, page);
|
||||
page--;
|
||||
List<LeaderBoardEntry> entries = leaderBoardData.getEntries();
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ExperienceLevelServiceBeanTest {
|
||||
public void testExperienceToNextLevelCalculation() {
|
||||
AExperienceLevel level = mock(AExperienceLevel.class);
|
||||
when(level.getExperienceNeeded()).thenReturn(15L);
|
||||
when(experienceLevelManagementService.getLevel(51)).thenReturn(Optional.of(level));
|
||||
when(experienceLevelManagementService.getLevelOptional(51)).thenReturn(Optional.of(level));
|
||||
Long experience = testingUnit.calculateExperienceToNextLevel(50, 10L);
|
||||
Assert.assertEquals(5L, experience.longValue());
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class ExperienceLevelServiceBeanTest {
|
||||
|
||||
@Test(expected = AbstractoRunTimeException.class)
|
||||
public void testExperienceToNextLevelCalculationOverExistingLevel() {
|
||||
when(experienceLevelManagementService.getLevel(51)).thenReturn(Optional.empty());
|
||||
when(experienceLevelManagementService.getLevelOptional(51)).thenReturn(Optional.empty());
|
||||
testingUnit.calculateExperienceToNextLevel(50, 10L);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,65 +59,21 @@ public class ExperienceRoleServiceBeanTest {
|
||||
private static final Long CHANNEL_ID = 4L;
|
||||
private static final Long ROLE_ID = 5L;
|
||||
|
||||
@Test
|
||||
public void testSettingRoleToLevelWithoutOldUsers() {
|
||||
Integer levelCount = 10;
|
||||
Role roleToChange = Mockito.mock(Role.class);
|
||||
ARole role = Mockito.mock(ARole.class);
|
||||
when(roleToChange.getIdLong()).thenReturn(ROLE_ID);
|
||||
when(roleManagementService.findRole(ROLE_ID)).thenReturn(role);
|
||||
AExperienceRole previousExperienceRole = Mockito.mock(AExperienceRole.class);
|
||||
when(experienceRoleManagementService.getRoleInServerOptional(role)).thenReturn(Optional.of(previousExperienceRole));
|
||||
CompletableFuture<Void> future = testingUnit.setRoleToLevel(roleToChange, levelCount, CHANNEL_ID);
|
||||
|
||||
future.join();
|
||||
verify(experienceRoleManagementService, times(1)).unsetRole(previousExperienceRole);
|
||||
verify(self, times(1)).unsetRoleInDb(levelCount, ROLE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsetRoleInDb() {
|
||||
Integer levelCount = 10;
|
||||
AExperienceLevel level = Mockito.mock(AExperienceLevel.class);
|
||||
ARole roleToChange = Mockito.mock(ARole.class);
|
||||
when(roleToChange.getServer()).thenReturn(server);
|
||||
when(experienceLevelService.getLevel(levelCount)).thenReturn(Optional.of(level));
|
||||
when(experienceLevelService.getLevelOptional(levelCount)).thenReturn(Optional.of(level));
|
||||
when(roleManagementService.findRole(roleToChange.getId())).thenReturn(roleToChange);
|
||||
testingUnit.unsetRoleInDb(levelCount, roleToChange.getId());
|
||||
|
||||
verify(experienceRoleManagementService, times(1)).removeAllRoleAssignmentsForLevelInServer(level, server);
|
||||
verify(experienceRoleManagementService, times(1)).removeAllRoleAssignmentsForLevelInServerExceptRole(level, server, roleToChange);
|
||||
verify(experienceRoleManagementService, times(1)).setLevelToRole(level, roleToChange);
|
||||
verify(experienceRoleManagementService, times(0)).getExperienceRolesForServer(server);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSettingRoleToLevelExistingUsers() {
|
||||
Integer levelCount = 10;
|
||||
Role roleToChange = Mockito.mock(Role.class);
|
||||
ARole role = Mockito.mock(ARole.class);
|
||||
when(roleToChange.getIdLong()).thenReturn(ROLE_ID);
|
||||
when(roleManagementService.findRole(ROLE_ID)).thenReturn(role);
|
||||
when(role.getServer()).thenReturn(server);
|
||||
AUserExperience firstUser = Mockito.mock(AUserExperience.class);
|
||||
AUserExperience secondUser = Mockito.mock(AUserExperience.class);
|
||||
List<AUserExperience> users = Arrays.asList(firstUser, secondUser);
|
||||
AExperienceRole previousExperienceRole = Mockito.mock(AExperienceRole.class);
|
||||
when(previousExperienceRole.getUsers()).thenReturn(users);
|
||||
AExperienceRole newExperienceRole = Mockito.mock(AExperienceRole.class);
|
||||
when(experienceRoleManagementService.getRoleInServerOptional(role)).thenReturn(Optional.of(previousExperienceRole));
|
||||
when(experienceRoleManagementService.getExperienceRolesForServer(server)).thenReturn(new ArrayList<>(Arrays.asList(newExperienceRole, previousExperienceRole)));
|
||||
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
|
||||
futures.add(CompletableFuture.completedFuture(null));
|
||||
AChannel feedbackChannel = Mockito.mock(AChannel.class);
|
||||
when(channelManagementService.loadChannel(CHANNEL_ID)).thenReturn(feedbackChannel);
|
||||
CompletableFutureList<RoleCalculationResult> futuresList = new CompletableFutureList<>(futures);
|
||||
when(userExperienceService.executeActionOnUserExperiencesWithFeedBack(eq(users), eq(feedbackChannel), any())).thenReturn(futuresList);
|
||||
CompletableFuture<Void> future = testingUnit.setRoleToLevel(roleToChange, levelCount, CHANNEL_ID);
|
||||
future.join();
|
||||
verify(experienceRoleManagementService, times(0)).unsetRole(previousExperienceRole);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateRoleForLevelInBetween() {
|
||||
List<AExperienceRole> roles = getExperienceRoles();
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ExperienceLevelManagementServiceBeanTest {
|
||||
when(level.getLevel()).thenReturn(levelValue);
|
||||
when(level.getExperienceNeeded()).thenReturn(experienceAmount);
|
||||
when(experienceLevelRepository.findById(levelValue)).thenReturn(Optional.of(level));
|
||||
Optional<AExperienceLevel> foundLevelOptional = testUnit.getLevel(levelValue);
|
||||
Optional<AExperienceLevel> foundLevelOptional = testUnit.getLevelOptional(levelValue);
|
||||
Assert.assertTrue(foundLevelOptional.isPresent());
|
||||
if(foundLevelOptional.isPresent()) {
|
||||
AExperienceLevel foundLevel = foundLevelOptional.get();
|
||||
@@ -70,7 +70,7 @@ public class ExperienceLevelManagementServiceBeanTest {
|
||||
int levelValue = 1;
|
||||
Optional<AExperienceLevel> level = Optional.empty();
|
||||
when(experienceLevelRepository.findById(levelValue)).thenReturn(level);
|
||||
Optional<AExperienceLevel> foundLevelOptional = testUnit.getLevel(levelValue);
|
||||
Optional<AExperienceLevel> foundLevelOptional = testUnit.getLevelOptional(levelValue);
|
||||
Assert.assertFalse(foundLevelOptional.isPresent());
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,14 @@ public class ExperienceRoleManagementServiceBeanTest {
|
||||
public void testRemovingAllRoleAssignmentsForLevel() {
|
||||
when(level.getLevel()).thenReturn(10);
|
||||
AExperienceRole secondRole = Mockito.mock(AExperienceRole.class);
|
||||
ARole anotherARole = Mockito.mock(ARole.class);
|
||||
when(anotherARole.getId()).thenReturn(ROLE_ID + 1);
|
||||
when(role.getId()).thenReturn(ROLE_ID);
|
||||
when(experienceRole.getRole()).thenReturn(anotherARole);
|
||||
when(secondRole.getRole()).thenReturn(anotherARole);
|
||||
List<AExperienceRole> experienceRoles = Arrays.asList(experienceRole, secondRole);
|
||||
when(experienceRoleRepository.findByLevelAndRoleServer(level, server)).thenReturn(experienceRoles);
|
||||
testUnit.removeAllRoleAssignmentsForLevelInServer(level, server);
|
||||
testUnit.removeAllRoleAssignmentsForLevelInServerExceptRole(level, server, role);
|
||||
verify(experienceRoleRepository, times(1)).findByLevelAndRoleServer(level, server);
|
||||
verify(experienceRoleRepository, times(experienceRoles.size())).delete(roleArgumentCaptor.capture());
|
||||
List<AExperienceRole> allValues = roleArgumentCaptor.getAllValues();
|
||||
@@ -66,7 +71,7 @@ public class ExperienceRoleManagementServiceBeanTest {
|
||||
when(level.getLevel()).thenReturn(10);
|
||||
List<AExperienceRole> experienceRoles = new ArrayList<>();
|
||||
when(experienceRoleRepository.findByLevelAndRoleServer(level, server)).thenReturn(experienceRoles);
|
||||
testUnit.removeAllRoleAssignmentsForLevelInServer(level, server);
|
||||
testUnit.removeAllRoleAssignmentsForLevelInServerExceptRole(level, server, role);
|
||||
verify(experienceRoleRepository, times(1)).findByLevelAndRoleServer(level, server);
|
||||
verify(experienceRoleRepository, times(experienceRoles.size())).delete(roleArgumentCaptor.capture());
|
||||
List<AExperienceRole> allValues = roleArgumentCaptor.getAllValues();
|
||||
|
||||
@@ -62,7 +62,7 @@ public class UserExperienceManagementServiceBeanTest {
|
||||
when(repository.findById(USER_IN_SERVER_ID)).thenReturn(Optional.empty());
|
||||
AExperienceLevel startLevel = Mockito.mock(AExperienceLevel.class);
|
||||
when(startLevel.getLevel()).thenReturn(START_LEVEL);
|
||||
when(experienceLevelManagementService.getLevel(START_LEVEL)).thenReturn(Optional.of(startLevel));
|
||||
when(experienceLevelManagementService.getLevelOptional(START_LEVEL)).thenReturn(Optional.of(startLevel));
|
||||
AUserExperience userInServer = testUnit.findUserInServer(user);
|
||||
Assert.assertEquals(0L, userInServer.getExperience().longValue());
|
||||
Assert.assertEquals(0L, userInServer.getMessageCount().longValue());
|
||||
@@ -81,7 +81,7 @@ public class UserExperienceManagementServiceBeanTest {
|
||||
when(user.getUserReference()).thenReturn(aUser);
|
||||
AExperienceLevel startLevel = Mockito.mock(AExperienceLevel.class);
|
||||
when(startLevel.getLevel()).thenReturn(START_LEVEL);
|
||||
when(experienceLevelManagementService.getLevel(START_LEVEL)).thenReturn(Optional.of(startLevel));
|
||||
when(experienceLevelManagementService.getLevelOptional(START_LEVEL)).thenReturn(Optional.of(startLevel));
|
||||
AUserExperience userInServer = testUnit.createUserInServer(user);
|
||||
Assert.assertEquals(0L, userInServer.getExperience().longValue());
|
||||
Assert.assertEquals(0L, userInServer.getMessageCount().longValue());
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.experience.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExperienceRoleNotFoundException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
public ExperienceRoleNotFoundException() {
|
||||
super("Experience role was not found for role.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "experience_role_not_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.experience.model.template;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -15,13 +16,14 @@ import java.io.Serializable;
|
||||
@Getter
|
||||
@Builder
|
||||
public class LeaderBoardEntryModel implements Serializable {
|
||||
/**
|
||||
* The {@link AUserExperience experience} for this particular user in the server
|
||||
*/
|
||||
private AUserExperience experience;
|
||||
private Long experience;
|
||||
private Long messageCount;
|
||||
private Long userId;
|
||||
private Integer level;
|
||||
/**
|
||||
* The {@link Member member} associated wit this user experience, might be null if the user left he server.
|
||||
*/
|
||||
@Setter
|
||||
private transient Member member;
|
||||
/**
|
||||
* The position this {@link dev.sheldan.abstracto.core.models.database.AUserInAServer user} in this server has, ordered by experience {@link AUserExperience#experience}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.experience.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class LevelRole {
|
||||
private Role role;
|
||||
private Long roleId;
|
||||
private Integer level;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.experience.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LevelRolesModel {
|
||||
private List<LevelRole> levelRoles;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package dev.sheldan.abstracto.experience.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.SlimUserInitiatedServerContext;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
/**
|
||||
* Object containing the provided property to render the rank command template. This includes the
|
||||
@@ -12,8 +12,8 @@ import lombok.experimental.SuperBuilder;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class RankModel extends SlimUserInitiatedServerContext {
|
||||
@Builder
|
||||
public class RankModel {
|
||||
/**
|
||||
* The {@link LeaderBoardEntryModel} containing the experience information about the user executing the rank
|
||||
* command.
|
||||
@@ -23,4 +23,8 @@ public class RankModel extends SlimUserInitiatedServerContext {
|
||||
* The necessary experience to the next level up.
|
||||
*/
|
||||
private Long experienceToNextLevel;
|
||||
/**
|
||||
* The member to show the rank for
|
||||
*/
|
||||
private Member member;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import dev.sheldan.abstracto.experience.model.ServerExperience;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -22,6 +23,7 @@ import java.util.function.Function;
|
||||
* user in the guild and retrieving {@link LeaderBoard leaderboard} data.
|
||||
*/
|
||||
public interface AUserExperienceService {
|
||||
String EXPERIENCE_GAIN_CHANNEL_GROUP_KEY = "experienceGain";
|
||||
/**
|
||||
* Adds the given {@link AUserInAServer userInAServer} to the list of user who gained experience in the current minute.
|
||||
* Does not add the user to the list of users, if it is already in there.
|
||||
@@ -150,4 +152,9 @@ public interface AUserExperienceService {
|
||||
* @param results The list of {@link RoleCalculationResult} which should be updated in the database
|
||||
*/
|
||||
void syncRolesInStorage(List<RoleCalculationResult> results);
|
||||
|
||||
boolean experienceGainEnabledInChannel(MessageChannel messageChannel);
|
||||
|
||||
AUserExperience createUserExperienceForUser(AUserInAServer aUserInAServer, Long experience, Long messageCount);
|
||||
AUserExperience createUserExperienceForUser(AUserInAServer aUserInAServer, Long experience, Long messageCount, List<AExperienceLevel> levels);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.model.template.LevelRole;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.util.List;
|
||||
@@ -38,7 +39,10 @@ public interface ExperienceRoleService {
|
||||
* @return A {@link CompletableFuture future} which completes, after all the updates on the {@link net.dv8tion.jda.api.entities.Member}
|
||||
* have been completed
|
||||
*/
|
||||
CompletableFuture<Void> unsetRole(ARole role, Long channelId);
|
||||
CompletableFuture<Void> unsetRoles(ARole role, Long channelId);
|
||||
List<AExperienceRole> getExperienceRolesAtLevel(Integer level, AServer server);
|
||||
CompletableFuture<Void> unsetRoles(List<ARole> roles, Long channelId);
|
||||
CompletableFuture<Void> unsetRoles(List<ARole> roles, Long channelId, AExperienceRole toAdd);
|
||||
|
||||
/**
|
||||
* Calculates the appropriate {@link AExperienceRole experienceRole} based on the provided list of {@link AExperienceRole experienceRole}
|
||||
@@ -57,4 +61,5 @@ public interface ExperienceRoleService {
|
||||
* @return The next {@link AExperienceLevel} a {@link AExperienceRole} is awarded at, this will be null if there are no roles or there is no further role to reach
|
||||
*/
|
||||
AExperienceLevel getLevelOfNextRole(AExperienceLevel startLevel, AServer server);
|
||||
List<LevelRole> loadLevelRoleConfigForServer(AServer server);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ public interface ExperienceLevelManagementService {
|
||||
* @param level The {@link AExperienceLevel level} of the wanted level number
|
||||
* @return Returns an optional containing the {@link AExperienceLevel level} if it exists, and empty otherwise
|
||||
*/
|
||||
Optional<AExperienceLevel> getLevel(Integer level);
|
||||
Optional<AExperienceLevel> getLevelOptional(Integer level);
|
||||
AExperienceLevel getLevel(Integer level);
|
||||
|
||||
/**
|
||||
* Loads the complete level configuration and returns all found {@link AExperienceLevel levels} from the database.
|
||||
|
||||
@@ -23,13 +23,14 @@ public interface ExperienceRoleManagementService {
|
||||
* @return the created or updated {@link AExperienceRole experienceRole}
|
||||
*/
|
||||
AExperienceRole setLevelToRole(AExperienceLevel level, ARole role);
|
||||
List<AExperienceRole> getExperienceRolesAtLevelInServer(AExperienceLevel level, AServer server);
|
||||
|
||||
/**
|
||||
* Deletes *all* (if there are multiple by some chance) roles which were set to be given at the provided {@link AExperienceLevel level} in the {@link AServer server}
|
||||
* @param level The level to remove the roles for
|
||||
* @param server The server in which this should happen
|
||||
*/
|
||||
void removeAllRoleAssignmentsForLevelInServer(AExperienceLevel level, AServer server);
|
||||
void removeAllRoleAssignmentsForLevelInServerExceptRole(AExperienceLevel level, AServer server, ARole role);
|
||||
|
||||
/**
|
||||
* Deletes a singular {@link AExperienceRole experienceRole} directly.
|
||||
|
||||
@@ -52,11 +52,11 @@ public interface UserExperienceManagementService {
|
||||
/**
|
||||
* Retrieves a list of {@link AUserExperience} ordered by {@link AUserExperience#experience} and only returns the positions between {@code start} and @{code end}.
|
||||
* @param server The {@link AServer} to retrieve the users for
|
||||
* @param start The start index in the complete ordered list to return the {@link AUserExperience} elements for
|
||||
* @param end The end index for which to return a sublist of {@link AUserExperience} elements for
|
||||
* @param page The page to retrieve
|
||||
* @param size The size of each page
|
||||
* @return A list desc ordered by {@link AUserExperience#experience} only containing the elements between {@code start} and @{code end}
|
||||
*/
|
||||
List<AUserExperience> findLeaderBoardUsersPaginated(AServer server, Integer start, Integer end);
|
||||
List<AUserExperience> findLeaderBoardUsersPaginated(AServer server, Integer page, Integer size);
|
||||
|
||||
/**
|
||||
* Returns the {@link LeaderBoardEntryResult} of the given {@link AUserExperience}.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ public class RemindServiceBean implements ReminderService {
|
||||
parameters.put("reminderId", reminder.getId().toString());
|
||||
JobParameters jobParameters = JobParameters.builder().parameters(parameters).build();
|
||||
String triggerKey = schedulerService.executeJobWithParametersOnce("reminderJob", "utility", jobParameters, Date.from(reminder.getTargetDate()));
|
||||
log.info("Starting scheduled job with trigger {} to execute reminder. {}", triggerKey, reminder.getId());
|
||||
log.info("Starting scheduled job with trigger {} to execute reminder {}.", triggerKey, reminder.getId());
|
||||
reminder.setJobTriggerKey(triggerKey);
|
||||
reminderManagementService.saveReminder(reminder);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -21,6 +21,13 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.scheduling</groupId>
|
||||
<artifactId>scheduling-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package dev.sheldan.abstracto.suggestion.job;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@DisallowConcurrentExecution
|
||||
@Component
|
||||
@Getter
|
||||
@Setter
|
||||
@PersistJobDataAfterExecution
|
||||
public class SuggestionReminderJob extends QuartzJobBean {
|
||||
|
||||
@Autowired
|
||||
private SuggestionService suggestionService;
|
||||
|
||||
private Long suggestionId;
|
||||
private Long serverId;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
log.info("Executing suggestion reminder job for suggestion {} in server {}", suggestionId, serverId);
|
||||
try {
|
||||
suggestionService.remindAboutSuggestion(new ServerSpecificId(serverId, suggestionId));
|
||||
} catch (Exception exception) {
|
||||
log.error("Suggestion reminder job failed.", exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package dev.sheldan.abstracto.suggestion.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
@@ -8,11 +11,16 @@ import dev.sheldan.abstracto.core.service.management.UserInServerManagementServi
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureMode;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionPostTarget;
|
||||
import dev.sheldan.abstracto.suggestion.exception.UnSuggestNotPossibleException;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.Suggestion;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.SuggestionState;
|
||||
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
|
||||
import dev.sheldan.abstracto.suggestion.model.template.SuggestionReminderModel;
|
||||
import dev.sheldan.abstracto.suggestion.service.management.SuggestionManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
@@ -24,6 +32,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -36,6 +46,7 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
public static final String SUGGESTION_YES_EMOTE = "suggestionYes";
|
||||
public static final String SUGGESTION_NO_EMOTE = "suggestionNo";
|
||||
public static final String SUGGESTION_COUNTER_KEY = "suggestion";
|
||||
public static final String SUGGESTION_REMINDER_TEMPLATE_KEY = "suggest_suggestion_reminder";
|
||||
|
||||
@Autowired
|
||||
private SuggestionManagementService suggestionManagementService;
|
||||
@@ -73,6 +84,15 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private SchedulerService schedulerService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Value("${abstracto.feature.suggestion.removalMaxAge}")
|
||||
private Long removalMaxAgeSeconds;
|
||||
|
||||
@@ -114,8 +134,25 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
|
||||
@Transactional
|
||||
public void persistSuggestionInDatabase(Member member, String text, Message message, Long suggestionId, Message commandMessage) {
|
||||
log.info("Persisting suggestion {} for server {} in database.", suggestionId, member.getGuild().getId());
|
||||
suggestionManagementService.createSuggestion(member, text, message, suggestionId, commandMessage);
|
||||
Long serverId = member.getGuild().getIdLong();
|
||||
log.info("Persisting suggestion {} for server {} in database.", suggestionId, serverId);
|
||||
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text, message, suggestionId, commandMessage);
|
||||
if(featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_REMINDER)) {
|
||||
String triggerKey = scheduleSuggestionReminder(serverId, suggestionId);
|
||||
suggestion.setSuggestionReminderJobTriggerKey(triggerKey);
|
||||
}
|
||||
}
|
||||
|
||||
private String scheduleSuggestionReminder(Long serverId, Long suggestionId) {
|
||||
HashMap<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put("serverId", serverId.toString());
|
||||
parameters.put("suggestionId", suggestionId.toString());
|
||||
JobParameters jobParameters = JobParameters.builder().parameters(parameters).build();
|
||||
Long days = configService.getLongValueOrConfigDefault(SuggestionService.SUGGESTION_REMINDER_DAYS_CONFIG_KEY, serverId);
|
||||
Instant targetDate = Instant.now().plus(days, ChronoUnit.DAYS);
|
||||
String triggerKey = schedulerService.executeJobWithParametersOnce("suggestionReminderJob", "suggestion", jobParameters, Date.from(targetDate));
|
||||
log.info("Starting scheduled job with trigger {} to execute suggestion reminder in server {} for suggestion {}.", triggerKey, serverId, suggestionId);
|
||||
return triggerKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,6 +160,7 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
Long serverId = commandMessage.getGuild().getIdLong();
|
||||
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
|
||||
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.ACCEPTED);
|
||||
cancelSuggestionReminder(suggestion);
|
||||
log.info("Accepting suggestion {} in server {}.", suggestionId, suggestion.getServer().getId());
|
||||
return updateSuggestion(commandMessage.getMember(), text, suggestion);
|
||||
}
|
||||
@@ -132,6 +170,7 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
Long serverId = commandMessage.getGuild().getIdLong();
|
||||
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
|
||||
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.VETOED);
|
||||
cancelSuggestionReminder(suggestion);
|
||||
log.info("Vetoing suggestion {} in server {}.", suggestionId, suggestion.getServer().getId());
|
||||
return updateSuggestion(commandMessage.getMember(), text, suggestion);
|
||||
}
|
||||
@@ -186,6 +225,7 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
Long serverId = commandMessage.getGuild().getIdLong();
|
||||
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
|
||||
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.REJECTED);
|
||||
cancelSuggestionReminder(suggestion);
|
||||
log.info("Rejecting suggestion {} in server {}.", suggestionId, suggestion.getServer().getId());
|
||||
return updateSuggestion(commandMessage.getMember(), text, suggestion);
|
||||
}
|
||||
@@ -199,7 +239,12 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
throw new UnSuggestNotPossibleException();
|
||||
}
|
||||
return messageService.deleteMessageInChannelInServer(suggestion.getServer().getId(), suggestion.getChannel().getId(), suggestion.getMessageId())
|
||||
.thenAccept(unused -> self.deleteSuggestion(suggestionId, serverId));
|
||||
.thenAccept(unused -> self.deleteSuggestion(suggestionId, serverId))
|
||||
.exceptionally(throwable -> {
|
||||
log.info("Suggestion message for suggestion {} in server {} did not exist anymore - ignoring.", suggestionId, serverId);
|
||||
self.deleteSuggestion(suggestionId, serverId);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,8 +258,50 @@ public class SuggestionServiceBean implements SuggestionService {
|
||||
suggestionManagementService.deleteSuggestion(suggestionsToRemove);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> remindAboutSuggestion(ServerSpecificId suggestionId) {
|
||||
Long serverId = suggestionId.getServerId();
|
||||
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId.getId());
|
||||
ServerChannelMessage suggestionServerChannelMessage = ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(serverId)
|
||||
.channelId(suggestion.getChannel().getId())
|
||||
.messageId(suggestion.getMessageId())
|
||||
.build();
|
||||
ServerChannelMessage commandServerChannelMessage = ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(serverId)
|
||||
.channelId(suggestion.getCommandChannel().getId())
|
||||
.messageId(suggestion.getCommandMessageId())
|
||||
.build();
|
||||
SuggestionReminderModel model = SuggestionReminderModel
|
||||
.builder()
|
||||
.serverId(serverId)
|
||||
.serverUser(ServerUser.fromAUserInAServer(suggestion.getSuggester()))
|
||||
.suggestionCreationDate(suggestion.getCreated())
|
||||
.suggestionId(suggestionId.getId())
|
||||
.suggestionMessage(suggestionServerChannelMessage)
|
||||
.suggestionCommandMessage(commandServerChannelMessage)
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(SUGGESTION_REMINDER_TEMPLATE_KEY, model, serverId);
|
||||
log.info("Reminding about suggestion {} in server {}.", suggestionId.getId(), serverId);
|
||||
List<CompletableFuture<Message>> completableFutures = postTargetService.sendEmbedInPostTarget(messageToSend, SuggestionPostTarget.SUGGESTION, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(completableFutures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelSuggestionReminder(Suggestion suggestion) {
|
||||
if(suggestion.getSuggestionReminderJobTriggerKey() != null) {
|
||||
log.info("Cancelling reminder for suggestion {} in server {}.", suggestion.getSuggestionId().getId(), suggestion.getSuggestionId().getServerId());
|
||||
schedulerService.stopTrigger(suggestion.getSuggestionReminderJobTriggerKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteSuggestion(Long suggestionId, Long serverId) {
|
||||
suggestionManagementService.deleteSuggestion(serverId, suggestionId);
|
||||
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
|
||||
cancelSuggestionReminder(suggestion);
|
||||
suggestionManagementService.deleteSuggestion(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="suggestionReminderJob.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="suggestion-reminder-job-insert">
|
||||
<insert tableName="scheduler_job">
|
||||
<column name="name" value="suggestionReminderJob"/>
|
||||
<column name="group_name" value="suggestion"/>
|
||||
<column name="clazz" value="dev.sheldan.abstracto.suggestion.job.SuggestionReminderJob"/>
|
||||
<column name="active" value="true"/>
|
||||
<column name="recovery" value="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="suggestion-addTriggerColumn">
|
||||
<addColumn tableName="suggestion" >
|
||||
<column name="job_trigger_key"
|
||||
type="varchar(255)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="suggestion.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -8,4 +8,5 @@
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="1.0-suggestion/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.13/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -2,6 +2,14 @@ abstracto.featureFlags.suggestion.featureName=suggestion
|
||||
abstracto.featureFlags.suggestion.enabled=false
|
||||
|
||||
abstracto.postTargets.suggestions.name=suggestions
|
||||
abstracto.postTargets.suggestionReminder.name=suggestionReminder
|
||||
|
||||
abstracto.feature.suggestion.removalMaxAge=3600
|
||||
abstracto.feature.suggestion.removalDays=2
|
||||
abstracto.feature.suggestion.removalDays=2
|
||||
|
||||
abstracto.featureModes.suggestionReminder.featureName=suggestion
|
||||
abstracto.featureModes.suggestionReminder.mode=suggestionReminder
|
||||
abstracto.featureModes.suggestionReminder.enabled=false
|
||||
|
||||
abstracto.systemConfigs.suggestionReminderDays.name=suggestionReminderDays
|
||||
abstracto.systemConfigs.suggestionReminderDays.longValue=7
|
||||
@@ -11,9 +11,10 @@ import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureDefinition;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionFeatureMode;
|
||||
import dev.sheldan.abstracto.suggestion.config.SuggestionPostTarget;
|
||||
import dev.sheldan.abstracto.suggestion.exception.SuggestionNotFoundException;
|
||||
import dev.sheldan.abstracto.suggestion.exception.UnSuggestNotPossibleException;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.Suggestion;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.SuggestionState;
|
||||
import dev.sheldan.abstracto.suggestion.model.template.SuggestionLog;
|
||||
@@ -76,6 +77,9 @@ public class SuggestionServiceBeanTest {
|
||||
@Mock
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Mock
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Mock
|
||||
private UserService userService;
|
||||
|
||||
@@ -125,10 +129,11 @@ public class SuggestionServiceBeanTest {
|
||||
@Test
|
||||
public void testCreateSuggestion() {
|
||||
when(member.getGuild()).thenReturn(guild);
|
||||
when(guild.getId()).thenReturn("5");
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
String text = "text";
|
||||
Message message = Mockito.mock(Message.class);
|
||||
Message commandMessage = Mockito.mock(Message.class);
|
||||
when(featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, SERVER_ID, SuggestionFeatureMode.SUGGESTION_REMINDER)).thenReturn(false);
|
||||
testUnit.persistSuggestionInDatabase(member, text, message, SUGGESTION_ID, commandMessage);
|
||||
verify(suggestionManagementService, times(1)).createSuggestion(member, text, message, SUGGESTION_ID, commandMessage);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ package dev.sheldan.abstracto.suggestion.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -18,11 +20,21 @@ public class SuggestionFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<PostTargetEnum> getRequiredPostTargets() {
|
||||
return Arrays.asList(SuggestionPostTarget.SUGGESTION);
|
||||
return Arrays.asList(SuggestionPostTarget.SUGGESTION, SuggestionPostTarget.SUGGESTION_REMINDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredEmotes() {
|
||||
return Arrays.asList("suggestionYes", "suggestionNo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(SuggestionFeatureMode.SUGGESTION_REMINDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredSystemConfigKeys() {
|
||||
return Arrays.asList(SuggestionService.SUGGESTION_REMINDER_DAYS_CONFIG_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.suggestion.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum SuggestionFeatureMode implements FeatureMode {
|
||||
SUGGESTION_REMINDER("suggestionReminder");
|
||||
|
||||
private final String key;
|
||||
|
||||
SuggestionFeatureMode(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum SuggestionPostTarget implements PostTargetEnum {
|
||||
SUGGESTION("suggestions");
|
||||
SUGGESTION("suggestions"), SUGGESTION_REMINDER("suggestionReminder");
|
||||
|
||||
private String key;
|
||||
|
||||
|
||||
@@ -66,4 +66,7 @@ public class Suggestion implements Serializable {
|
||||
@Column(name = "command_message_id")
|
||||
private Long commandMessageId;
|
||||
|
||||
@Column(name = "job_trigger_key")
|
||||
private String suggestionReminderJobTriggerKey;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.suggestion.model.template;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class SuggestionReminderModel {
|
||||
private Long serverId;
|
||||
private Long suggestionId;
|
||||
private Instant suggestionCreationDate;
|
||||
private ServerChannelMessage suggestionMessage;
|
||||
private ServerChannelMessage suggestionCommandMessage;
|
||||
private ServerUser serverUser;
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
package dev.sheldan.abstracto.suggestion.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.suggestion.model.database.Suggestion;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface SuggestionService {
|
||||
String SUGGESTION_REMINDER_DAYS_CONFIG_KEY = "suggestionReminderDays";
|
||||
CompletableFuture<Void> createSuggestionMessage(Message commandMessage, String text);
|
||||
CompletableFuture<Void> acceptSuggestion(Long suggestionId, Message commandMessage, String text);
|
||||
CompletableFuture<Void> vetoSuggestion(Long suggestionId, Message commandMessage, String text);
|
||||
CompletableFuture<Void> rejectSuggestion(Long suggestionId, Message commandMessage, String text);
|
||||
CompletableFuture<Void> removeSuggestion(Long suggestionId, Member member);
|
||||
void cleanUpSuggestions();
|
||||
CompletableFuture<Void> remindAboutSuggestion(ServerSpecificId suggestionId);
|
||||
void cancelSuggestionReminder(Suggestion suggestion);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.2.14</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