mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-14 11:48:16 +00:00
[AB-57] [AB-61] reworked commands and services to work with completable futures and moved the database operations to the very last operation so we have transaction safety in more areas
added some cache annotations to the default repository functions reworked how the undo cations are processed within commands, they are executed in a post command listener when the state is error added a counter id to generate ids to be unique within servers, changed a few tables to be unique within a server added future utils class for wrapping a list of futures into one moved abstracto tables to separate schema in the installer refactored experience gain to work with more futures and delayed database access
This commit is contained in:
@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoard;
|
||||
@@ -23,6 +24,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -46,7 +48,7 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
// parameter is optional, in case its not present, we default to the 0th page
|
||||
@@ -58,9 +60,9 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
leaderBoardModel.setUserExecuting(converter.fromLeaderBoardEntry(userRank));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(LEADER_BOARD_POST_EMBED_TEMPLATE, leaderBoardModel);
|
||||
channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel());
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,6 +74,7 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
.name("leaderboard")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -11,16 +11,19 @@ import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.FullRole;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
|
||||
import dev.sheldan.abstracto.experience.models.database.ADisabledExpRole;
|
||||
import dev.sheldan.abstracto.experience.models.templates.DisabledExperienceRolesModel;
|
||||
import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Creates an embed containing the roles for which the experience gain has been disabled.
|
||||
@@ -38,7 +41,7 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
|
||||
private ChannelService channelService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
List<ADisabledExpRole> disabledRolesForServer = disabledExpRoleManagementService.getDisabledRolesForServer(commandContext.getUserInitiatedContext().getServer());
|
||||
DisabledExperienceRolesModel disabledExperienceRolesModel = (DisabledExperienceRolesModel) ContextConverter.fromCommandContext(commandContext, DisabledExperienceRolesModel.class);
|
||||
@@ -50,8 +53,8 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
|
||||
.build();
|
||||
disabledExperienceRolesModel.getRoles().add(role);
|
||||
});
|
||||
channelService.sendEmbedTemplateInChannel("list_disabled_experience_roles", disabledExperienceRolesModel, commandContext.getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
List<CompletableFuture<Message>> futures = channelService.sendEmbedTemplateInChannel("list_disabled_experience_roles", disabledExperienceRolesModel, commandContext.getChannel());
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.features.ExperienceFeature;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
@@ -23,6 +24,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Command used to show an embed containing information about the experience amount, level and message count of a ember on a server
|
||||
@@ -48,7 +50,7 @@ public class Rank extends AbstractConditionableCommand {
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
RankModel rankModel = (RankModel) ContextConverter.fromCommandContext(commandContext, RankModel.class);
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
@@ -56,9 +58,8 @@ public class Rank extends AbstractConditionableCommand {
|
||||
AUserExperience experienceObj = userRank.getExperience();
|
||||
rankModel.setExperienceToNextLevel(experienceLevelService.calculateExperienceToNextLevel(experienceObj.getCurrentLevel().getLevel(), experienceObj.getExperience()));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(RANK_POST_EMBED_TEMPLATE, rankModel);
|
||||
channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel());
|
||||
|
||||
return CommandResult.fromSuccess();
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,6 +70,7 @@ public class Rank extends AbstractConditionableCommand {
|
||||
.name("rank")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Command used to define which commands are to be awarded at which level
|
||||
@@ -34,7 +35,7 @@ public class SetExpRole extends AbstractConditionableCommand {
|
||||
private RoleService roleService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
Integer level = (Integer) commandContext.getParameters().getParameters().get(0);
|
||||
ARole role = (ARole) commandContext.getParameters().getParameters().get(1);
|
||||
@@ -43,8 +44,8 @@ public class SetExpRole extends AbstractConditionableCommand {
|
||||
throw new RoleNotFoundInGuildException(role.getId(), server.getId());
|
||||
}
|
||||
log.info("Setting role {} to be used for level {} on server {}", role.getId(), level, server.getId());
|
||||
experienceRoleService.setRoleToLevel(role, level, commandContext.getUserInitiatedContext().getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
return experienceRoleService.setRoleToLevel(role, level, commandContext.getUserInitiatedContext().getChannel())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,6 +58,7 @@ public class SetExpRole extends AbstractConditionableCommand {
|
||||
.name("setExpRole")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Command used to synchronize the actual awarded roles which what is defined to be awarded in the database.
|
||||
@@ -31,11 +32,11 @@ public class SyncRoles extends AbstractConditionableCommand {
|
||||
private AUserExperienceService userExperienceService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
AServer server = commandContext.getUserInitiatedContext().getServer();
|
||||
log.info("Synchronizing roles on server {}", server.getId());
|
||||
userExperienceService.syncUserRolesWithFeedback(server, commandContext.getUserInitiatedContext().getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
return userExperienceService.syncUserRolesWithFeedback(server, commandContext.getUserInitiatedContext().getChannel())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,6 +47,7 @@ public class SyncRoles extends AbstractConditionableCommand {
|
||||
.name("syncExpRoles")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Command used to remove a role from the roles to be awarded at certain levels. If there are users with this role currently, their role
|
||||
@@ -27,13 +28,13 @@ public class UnSetExpRole extends AbstractConditionableCommand {
|
||||
private ExperienceRoleService experienceRoleService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
checkParameters(commandContext);
|
||||
ARole role = (ARole) commandContext.getParameters().getParameters().get(0);
|
||||
// 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
|
||||
experienceRoleService.unsetRole(role, commandContext.getUserInitiatedContext().getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
return experienceRoleService.unsetRole(role, commandContext.getUserInitiatedContext().getChannel())
|
||||
.thenApply(aVoid -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,6 +46,7 @@ public class UnSetExpRole extends AbstractConditionableCommand {
|
||||
.name("unSetExpRole")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.causesReaction(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -30,9 +30,12 @@ public class JoiningUserRoleListener implements JoinListener {
|
||||
@Override
|
||||
public void execute(Member member, Guild guild, AUserInAServer aUserInAServer) {
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(aUserInAServer);
|
||||
Long userInServerId = aUserInAServer.getUserInServerId();
|
||||
if(userExperience != null) {
|
||||
log.info("User {} joined {} with previous experience. Setting up experience role again (if necessary).", member.getUser().getIdLong(), guild.getIdLong());
|
||||
userExperienceService.syncForSingleUser(userExperience);
|
||||
userExperienceService.syncForSingleUser(userExperience).thenAccept(result ->
|
||||
log.trace("Finished re-assigning experience for re-joning user {} in server {}.", userInServerId, guild.getIdLong())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@ import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.models.database.ADisabledExpRole;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.QueryHint;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -13,10 +15,15 @@ import java.util.List;
|
||||
*/
|
||||
@Repository
|
||||
public interface DisabledExpRoleRepository extends JpaRepository<ADisabledExpRole, Long> {
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
boolean existsByRole(ARole role);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
ADisabledExpRole findByRole(ARole role);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
void deleteByRole(ARole role);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
List<ADisabledExpRole> getByRole_Server(AServer server);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
package dev.sheldan.abstracto.experience.repository;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.QueryHint;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Repository to manage the access to the table managed by {@link AExperienceLevel}
|
||||
*/
|
||||
@Repository
|
||||
public interface ExperienceLevelRepository extends JpaRepository<AExperienceLevel, Integer> {
|
||||
@NotNull
|
||||
@Override
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
Optional<AExperienceLevel> findById(@NonNull Integer aLong);
|
||||
|
||||
@Override
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
boolean existsById(@NonNull Integer aLong);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
List<AExperienceLevel> findAll();
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.QueryHint;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Repository to manage the access to the table managed by {@link AExperienceRole}
|
||||
@@ -22,7 +25,7 @@ public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole,
|
||||
* @return The {@link AExperienceRole} found or null if the query did not return any results
|
||||
*/
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
AExperienceRole findByRole(ARole role);
|
||||
Optional<AExperienceRole> findByRole(ARole role);
|
||||
|
||||
/**
|
||||
* Finds a list of {@link AExperienceRole} (if there are multiple ones, because of misconfiguration) of the given
|
||||
@@ -41,4 +44,9 @@ public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole,
|
||||
*/
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
List<AExperienceRole> findByRoleServer(AServer server);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
Optional<AExperienceRole> findById(@NonNull Long aLong);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@ import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.experience.config.features.ExperienceFeatureConfig;
|
||||
import dev.sheldan.abstracto.experience.models.ExperienceGainResult;
|
||||
import dev.sheldan.abstracto.experience.models.RoleCalculationResult;
|
||||
import dev.sheldan.abstracto.experience.models.database.*;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
@@ -28,15 +33,16 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@@ -64,12 +70,18 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
@Autowired
|
||||
private DisabledExpRoleManagementService disabledExpRoleManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private RunTimeExperienceService runTimeExperienceService;
|
||||
|
||||
@Autowired
|
||||
private AUserExperienceServiceBean self;
|
||||
|
||||
/**
|
||||
* Creates the user in the runtime experience, if the user was not in yet. Also creates an entry for the minute, if necessary.
|
||||
* @param userInAServer The {@link AUserInAServer} to be added to the list of users gaining experience
|
||||
@@ -104,17 +116,17 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
|
||||
/**
|
||||
* Calculates the level of the given {@link AUserExperience} according to the given {@link AExperienceLevel} list
|
||||
* @param experience The {@link AUserExperience} to calculate the level for
|
||||
* @param levels The list of {@link AExperienceLevel} representing the level configuration, this must include the initial level 0
|
||||
* * This level will be taken as the initial value, and if no other level qualifies, this will be taken.
|
||||
* The levels must be ordered.
|
||||
* @param experienceCount
|
||||
* @return The appropriate level according to the level config
|
||||
*/
|
||||
@Override
|
||||
public AExperienceLevel calculateLevel(AUserExperience experience, List<AExperienceLevel> levels) {
|
||||
public AExperienceLevel calculateLevel(List<AExperienceLevel> levels, Long experienceCount) {
|
||||
AExperienceLevel lastLevel = levels.get(0);
|
||||
for (AExperienceLevel level : levels) {
|
||||
if(level.getExperienceNeeded() >= experience.getExperience()) {
|
||||
if(level.getExperienceNeeded() >= experienceCount) {
|
||||
return lastLevel;
|
||||
} else {
|
||||
lastLevel = level;
|
||||
@@ -124,9 +136,9 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateUserLevel(AUserExperience userExperience, List<AExperienceLevel> levels) {
|
||||
public boolean updateUserLevel(AUserExperience userExperience, List<AExperienceLevel> levels, Long experienceCount) {
|
||||
AUserInAServer user = userExperience.getUser();
|
||||
AExperienceLevel correctLevel = calculateLevel(userExperience, levels);
|
||||
AExperienceLevel correctLevel = calculateLevel(levels, experienceCount);
|
||||
Integer currentLevel = userExperience.getCurrentLevel() != null ? userExperience.getCurrentLevel().getLevel() : 0;
|
||||
if(!correctLevel.getLevel().equals(currentLevel)) {
|
||||
log.info("User {} leveled from {} to {}", user.getUserReference().getId(), currentLevel, correctLevel.getLevel());
|
||||
@@ -146,14 +158,17 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public void handleExperienceGain(List<AServer> servers) {
|
||||
public CompletableFuture<Void> handleExperienceGain(List<AServer> servers) {
|
||||
List<ExperienceGainResult> resultFutures = new ArrayList<>();
|
||||
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
// TODO what if there are a lot in here...., transaction size etc
|
||||
servers.forEach(serverExp -> {
|
||||
log.trace("Handling experience for server {}", serverExp.getId());
|
||||
int minExp = configService.getLongValue(ExperienceFeatureConfig.MIN_EXP_KEY, serverExp.getId()).intValue();
|
||||
int maxExp = configService.getLongValue(ExperienceFeatureConfig.MAX_EXP_KEY, serverExp.getId()).intValue();
|
||||
Double multiplier = configService.getDoubleValue(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverExp.getId());
|
||||
PrimitiveIterator.OfInt iterator = new Random().ints(serverExp.getUsers().size(), minExp, maxExp + 1).iterator();
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(serverExp);
|
||||
List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(serverExp);
|
||||
@@ -165,11 +180,23 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
Member member = botService.getMemberInServer(userInAServer);
|
||||
if(!roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
log.trace("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
AUserExperience aUserExperience = userExperienceManagementService.incrementExpForUser(userInAServer, gainedExperience.longValue(), 1L);
|
||||
AUserExperience aUserExperience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
|
||||
updateUserLevel(aUserExperience, levels);
|
||||
updateUserRole(aUserExperience, roles);
|
||||
userExperienceManagementService.saveUser(aUserExperience);
|
||||
Long newExperienceCount = aUserExperience.getExperience() + gainedExperience.longValue();
|
||||
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
|
||||
CompletableFuture<RoleCalculationResult> resultFuture = updateUserRole(aUserExperience, roles, newLevel.getLevel());
|
||||
Long newMessageCount = aUserExperience.getMessageCount() + 1L;
|
||||
ExperienceGainResult calculationResult =
|
||||
ExperienceGainResult
|
||||
.builder()
|
||||
.calculationResult(resultFuture)
|
||||
.newExperience(newExperienceCount)
|
||||
.newMessageCount(newMessageCount)
|
||||
.newLevel(newLevel.getLevel())
|
||||
.userInServerId(userInAServer.getUserInServerId())
|
||||
.build();
|
||||
resultFutures.add(calculationResult);
|
||||
futures.add(resultFuture);
|
||||
} else {
|
||||
log.trace("Experience gain was disabled. User did not gain any experience.");
|
||||
}
|
||||
@@ -178,6 +205,35 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenAccept(aVoid ->
|
||||
self.persistExperienceChanges(resultFutures)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistExperienceChanges(List<ExperienceGainResult> resultFutures) {
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
HashMap<Long, List<AExperienceRole>> serverRoleMapping = new HashMap<>();
|
||||
resultFutures.forEach(experienceGainResult -> {
|
||||
AUserInAServer user = userInServerManagementService.loadUser(experienceGainResult.getUserInServerId());
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(user);
|
||||
userExperience.setMessageCount(experienceGainResult.getNewMessageCount());
|
||||
userExperience.setExperience(experienceGainResult.getNewExperience());
|
||||
Optional<AExperienceLevel> foundLevel = levels.stream().filter(level -> level.getLevel().equals(experienceGainResult.getNewLevel())).findFirst();
|
||||
if(foundLevel.isPresent()) {
|
||||
userExperience.setCurrentLevel(foundLevel.get());
|
||||
} else {
|
||||
log.warn("User {} was present, but no level could be found.", userExperience.getUser().getUserReference().getId());
|
||||
}
|
||||
AServer server = user.getServerReference();
|
||||
if(!serverRoleMapping.containsKey(server.getId())) {
|
||||
serverRoleMapping.put(server.getId(), experienceRoleManagementService.getExperienceRolesForServer(server));
|
||||
}
|
||||
List<AExperienceRole> roleConfig = serverRoleMapping.get(server.getId());
|
||||
AExperienceRole role = experienceRoleService.calculateRole(roleConfig, userExperience.getLevelOrDefault());
|
||||
userExperience.setCurrentExperienceRole(role);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,28 +245,48 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
* @param roles The list of {@link AExperienceRole} used as a role configuration
|
||||
*/
|
||||
@Override
|
||||
public void updateUserRole(AUserExperience userExperience, List<AExperienceRole> roles) {
|
||||
public CompletableFuture<RoleCalculationResult> updateUserRole(AUserExperience userExperience, List<AExperienceRole> roles, Integer currentLevel) {
|
||||
AUserInAServer user = userExperience.getUser();
|
||||
Function<Void, RoleCalculationResult> returnNullRole = aVoid -> RoleCalculationResult
|
||||
.builder()
|
||||
.userInServerId(user.getUserInServerId())
|
||||
.experienceRoleId(null)
|
||||
.build();
|
||||
if(!botService.isUserInGuild(userExperience.getUser())) {
|
||||
log.trace("User {} is not in server {} anymore. No role calculation done.", userExperience.getUser().getUserInServerId(), userExperience.getUser().getServerReference().getId());
|
||||
return CompletableFuture.completedFuture(returnNullRole.apply(null));
|
||||
}
|
||||
Long userInServerId = user.getUserInServerId();
|
||||
log.trace("Updating experience role for user {} in server {}", user.getUserReference().getId(), user.getServerReference().getId());
|
||||
AExperienceRole role = experienceRoleService.calculateRole(userExperience, roles);
|
||||
AExperienceRole role = experienceRoleService.calculateRole(roles, currentLevel);
|
||||
Member member = botService.getMemberInServer(user.getServerReference(), user.getUserReference());
|
||||
boolean currentlyHasNoExperienceRole = userExperience.getCurrentExperienceRole() == null;
|
||||
if(role == null) {
|
||||
if(!currentlyHasNoExperienceRole && botService.isUserInGuild(userExperience.getUser())){
|
||||
roleService.removeRoleFromUser(user, userExperience.getCurrentExperienceRole().getRole());
|
||||
if(!currentlyHasNoExperienceRole){
|
||||
return roleService.removeRoleFromUserFuture(user, userExperience.getCurrentExperienceRole().getRole())
|
||||
.thenApply(returnNullRole);
|
||||
}
|
||||
userExperience.setCurrentExperienceRole(null);
|
||||
return;
|
||||
return CompletableFuture.completedFuture(returnNullRole.apply(null));
|
||||
}
|
||||
boolean userHasRoleAlready = roleService.memberHasRole(member, role.getRole());
|
||||
Long experienceRoleId = role.getId();
|
||||
Function<Void, RoleCalculationResult> fullResult = aVoid -> RoleCalculationResult
|
||||
.builder()
|
||||
.experienceRoleId(experienceRoleId)
|
||||
.userInServerId(userInServerId)
|
||||
.build();
|
||||
if(!userHasRoleAlready && (currentlyHasNoExperienceRole || !role.getRole().getId().equals(userExperience.getCurrentExperienceRole().getRole().getId()))) {
|
||||
log.info("User {} in server {} gets a new role {}", user.getUserReference().getId(), user.getServerReference().getId(), role.getRole().getId());
|
||||
CompletableFuture<Void> removalFuture;
|
||||
if(!currentlyHasNoExperienceRole && botService.isUserInGuild(userExperience.getUser())) {
|
||||
roleService.removeRoleFromUser(user, userExperience.getCurrentExperienceRole().getRole());
|
||||
removalFuture = roleService.removeRoleFromUserFuture(user, userExperience.getCurrentExperienceRole().getRole());
|
||||
} else {
|
||||
removalFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
roleService.addRoleToUser(user, role.getRole());
|
||||
CompletableFuture<Void> addRoleFuture = roleService.addRoleToUserFuture(user, role.getRole());
|
||||
return CompletableFuture.allOf(removalFuture, addRoleFuture).thenApply(fullResult);
|
||||
}
|
||||
userExperience.setCurrentExperienceRole(role);
|
||||
return CompletableFuture.completedFuture(fullResult.apply(null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,15 +295,17 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
* @param server The {@link AServer} to update the users for
|
||||
*/
|
||||
@Override
|
||||
public void syncUserRoles(AServer server) {
|
||||
public List<CompletableFuture<RoleCalculationResult>> syncUserRoles(AServer server) {
|
||||
List<CompletableFuture<RoleCalculationResult>> results = new ArrayList<>();
|
||||
List<AUserExperience> aUserExperiences = userExperienceManagementService.loadAllUsers(server);
|
||||
log.info("Found {} users to synchronize", aUserExperiences.size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
for (int i = 0; i < aUserExperiences.size(); i++) {
|
||||
AUserExperience userExperience = aUserExperiences.get(i);
|
||||
log.trace("Synchronizing {} out of {}", i, aUserExperiences.size());
|
||||
updateUserRole(userExperience, roles);
|
||||
results.add(updateUserRole(userExperience, roles, userExperience.getCurrentLevel().getLevel()));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,11 +314,35 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
* @param channel The {@link AChannel} in which the {@link dev.sheldan.abstracto.experience.models.templates.UserSyncStatusModel}
|
||||
*/
|
||||
@Override
|
||||
public void syncUserRolesWithFeedback(AServer server, AChannel channel) {
|
||||
public CompletableFuture<Void> syncUserRolesWithFeedback(AServer server, AChannel channel) {
|
||||
List<AUserExperience> aUserExperiences = userExperienceManagementService.loadAllUsers(server);
|
||||
log.info("Found {} users to synchronize", aUserExperiences.size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
executeActionOnUserExperiencesWithFeedBack(aUserExperiences, channel, (AUserExperience experience) -> updateUserRole(experience, roles));
|
||||
CompletableFutureList<RoleCalculationResult> calculations = executeActionOnUserExperiencesWithFeedBack(aUserExperiences, channel, (AUserExperience experience) -> updateUserRole(experience, roles, experience.getLevelOrDefault()));
|
||||
return calculations.getMainFuture().thenAccept(aVoid ->
|
||||
self.syncRolesInStorage(calculations.getObjects())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the actually stored experience roles in the database
|
||||
* @param results The list of {@link RoleCalculationResult} which should be applied
|
||||
*/
|
||||
@Transactional
|
||||
public void syncRolesInStorage(List<RoleCalculationResult> results) {
|
||||
results.forEach(result -> {
|
||||
if(result != null) {
|
||||
AUserInAServer user = userInServerManagementService.loadUser(result.getUserInServerId());
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(user);
|
||||
log.trace("Updating experience role for {} in server {} to {}", user.getUserInServerId(), user.getServerReference(), result.getExperienceRoleId());
|
||||
if(result.getExperienceRoleId() != null) {
|
||||
AExperienceRole role = experienceRoleManagementService.getExperienceRoleById(result.getExperienceRoleId());
|
||||
userExperience.setCurrentExperienceRole(role);
|
||||
} else {
|
||||
userExperience.setCurrentExperienceRole(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +352,8 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
* @param toExecute The {@link Consumer} which should be executed on each element of the passed list
|
||||
*/
|
||||
@Override
|
||||
public void executeActionOnUserExperiencesWithFeedBack(List<AUserExperience> experiences, AChannel channel, Consumer<AUserExperience> toExecute) {
|
||||
public CompletableFutureList<RoleCalculationResult> executeActionOnUserExperiencesWithFeedBack(List<AUserExperience> experiences, AChannel channel, Function<AUserExperience, CompletableFuture<RoleCalculationResult>> toExecute) {
|
||||
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
|
||||
MessageToSend status = getUserSyncStatusUpdateModel(0, experiences.size());
|
||||
try {
|
||||
Message statusMessage = messageService.createStatusMessage(status, channel).get();
|
||||
@@ -261,7 +364,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
status = getUserSyncStatusUpdateModel(i, experiences.size());
|
||||
messageService.updateStatusMessage(channel, statusMessage.getIdLong(), status);
|
||||
}
|
||||
toExecute.accept(experiences.get(i));
|
||||
futures.add(toExecute.apply(experiences.get(i)));
|
||||
log.trace("Synchronizing {} out of {}", i, experiences.size());
|
||||
}
|
||||
status = getUserSyncStatusUpdateModel(experiences.size(), experiences.size());
|
||||
@@ -270,6 +373,8 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
log.info("Failed to synchronize users.", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
return new CompletableFutureList<>(futures);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -294,11 +399,11 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
* @param userExperience The {@link AUserExperience} to synchronize the role for
|
||||
*/
|
||||
@Override
|
||||
public void syncForSingleUser(AUserExperience userExperience) {
|
||||
public CompletableFuture<RoleCalculationResult> syncForSingleUser(AUserExperience userExperience) {
|
||||
AUserInAServer user = userExperience.getUser();
|
||||
log.info("Synchronizing for user {} in server {}", user.getUserReference().getId(), user.getServerReference().getId());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(user.getServerReference());
|
||||
updateUserRole(userExperience, roles);
|
||||
return updateUserRole(userExperience, roles, userExperience.getLevelOrDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,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.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.experience.models.RoleCalculationResult;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
@@ -11,9 +14,12 @@ import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagem
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@@ -29,6 +35,12 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Autowired
|
||||
private AUserExperienceService userExperienceService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleServiceBean self;
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
/**
|
||||
* UnSets the current configuration for the passed level, and sets the {@link ARole} to be used for this level
|
||||
* in the given {@link AServer}
|
||||
@@ -36,11 +48,19 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
* @param level The level the {@link ARole} should be awarded at
|
||||
*/
|
||||
@Override
|
||||
public void setRoleToLevel(ARole role, Integer level, AChannel feedbackChannel) {
|
||||
public CompletableFuture<Void> setRoleToLevel(ARole role, Integer level, AChannel feedbackChannel) {
|
||||
Long roleId = role.getId();
|
||||
return unsetRole(role, feedbackChannel).thenAccept(aVoid ->
|
||||
self.unsetRoleInDb(level, roleId)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void unsetRoleInDb(Integer level, Long roleId) {
|
||||
AExperienceLevel experienceLevel = experienceLevelService.getLevel(level).orElseThrow(() -> new IllegalArgumentException(String.format("Could not find level %s", level)));
|
||||
unsetRole(role, feedbackChannel);
|
||||
experienceRoleManagementService.removeAllRoleAssignmentsForLevelInServer(experienceLevel, role.getServer());
|
||||
experienceRoleManagementService.setLevelToRole(experienceLevel, role);
|
||||
ARole loadedRole = roleManagementService.findRole(roleId);
|
||||
experienceRoleManagementService.removeAllRoleAssignmentsForLevelInServer(experienceLevel, loadedRole.getServer());
|
||||
experienceRoleManagementService.setLevelToRole(experienceLevel, loadedRole);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,35 +70,52 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
* configuration
|
||||
*/
|
||||
@Override
|
||||
public void unsetRole(ARole role, AChannel feedbackChannel) {
|
||||
AExperienceRole roleInServer = experienceRoleManagementService.getRoleInServer(role);
|
||||
if(roleInServer != null) {
|
||||
public CompletableFuture<Void> unsetRole(ARole role, AChannel feedbackChannel) {
|
||||
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()));
|
||||
|
||||
userExperienceService.executeActionOnUserExperiencesWithFeedBack(roleInServer.getUsers(), feedbackChannel,
|
||||
(AUserExperience ex) -> userExperienceService.updateUserRole(ex, roles));
|
||||
Long roleId = role.getId();
|
||||
CompletableFutureList<RoleCalculationResult> calculationResults = userExperienceService.executeActionOnUserExperiencesWithFeedBack(roleInServer.getUsers(), feedbackChannel,
|
||||
(AUserExperience ex) -> userExperienceService.updateUserRole(ex, roles, ex.getLevelOrDefault()));
|
||||
return calculationResults.getMainFuture().thenAccept(aVoid ->
|
||||
self.persistData(calculationResults, roleId)
|
||||
);
|
||||
} else {
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
} else {
|
||||
log.info("Experience role is not define in server - skipping unset.");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistData(CompletableFutureList<RoleCalculationResult> results, Long roleId) {
|
||||
AExperienceRole roleInServer = experienceRoleManagementService.getRoleInServer(roleId);
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
userExperienceService.syncRolesInStorage(results.getObjects());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the best {@link AExperienceRole} for the level of the passed {@link AUserExperience}
|
||||
* @param userExperience The {@link AUserExperience} containing the level to calculate the {@link AExperienceRole}
|
||||
* Finds the best {@link AExperienceRole} for the level of the passed {@link AUserExperience}, returns null if the passed
|
||||
* roles are empty/null
|
||||
* @param roles The role configuration to be used when calculating the appropriate {@link AExperienceRole}
|
||||
* @param currentLevel
|
||||
* @return The best fitting {@link AExperienceRole} according to the level of the {@link AUserExperience}
|
||||
*/
|
||||
@Override
|
||||
public AExperienceRole calculateRole(AUserExperience userExperience, List<AExperienceRole> roles) {
|
||||
if(roles.isEmpty()) {
|
||||
public AExperienceRole calculateRole(List<AExperienceRole> roles, Integer currentLevel) {
|
||||
if(roles == null || roles.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
AExperienceRole lastRole = null;
|
||||
for (AExperienceRole experienceRole : roles) {
|
||||
if(userExperience.getCurrentLevel().getLevel() >= experienceRole.getLevel().getLevel()) {
|
||||
if(currentLevel >= experienceRole.getLevel().getLevel()) {
|
||||
lastRole = experienceRole;
|
||||
} else {
|
||||
return lastRole;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class HasLevelCondition implements SystemCondition {
|
||||
|
||||
Long userId = (Long) parameters.get(USER_ID_VARIABLE);
|
||||
Integer level = (Integer) parameters.get(LEVEL_VARIABLE);
|
||||
Optional<AUserInAServer> userInServerOptional = userInServerManagementService.loadUser(userId);
|
||||
Optional<AUserInAServer> userInServerOptional = userInServerManagementService.loadUserConditional(userId);
|
||||
if(userInServerOptional.isPresent()) {
|
||||
AUserInAServer userInServer = userInServerOptional.get();
|
||||
AUserExperience user = userExperienceManagementService.findUserInServer(userInServer);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.repository.ExperienceRoleRepository;
|
||||
@@ -10,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -18,6 +21,9 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
@Autowired
|
||||
private ExperienceRoleRepository experienceRoleRepository;
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
/**
|
||||
* Removes *all* assignments of roles for the given level
|
||||
* @param level The level to remove the roles for
|
||||
@@ -37,14 +43,35 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
|
||||
@Override
|
||||
public AExperienceRole getRoleInServer(ARole role) {
|
||||
return this.getRoleInServerOptional(role).orElseThrow(AbstractoRunTimeException::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AExperienceRole> getRoleInServerOptional(ARole role) {
|
||||
return experienceRoleRepository.findByRole(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceRole getRoleInServer(Long roleId) {
|
||||
ARole role = roleManagementService.findRole(roleId);
|
||||
return getRoleInServer(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceRole> getExperienceRolesForServer(AServer server) {
|
||||
return experienceRoleRepository.findByRoleServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceRole getExperienceRoleById(Long experienceRoleId) {
|
||||
return getExperienceRoleByIdOptional(experienceRoleId).orElseThrow(() -> new AbstractoRunTimeException("Experience role not found"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AExperienceRole> getExperienceRoleByIdOptional(Long experienceRoleId) {
|
||||
return experienceRoleRepository.findById(experienceRoleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new role if nothing is found, and if its found the experience role will be set to the given level.
|
||||
* @param level The {@link AExperienceLevel} to set the role for
|
||||
@@ -53,18 +80,20 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
*/
|
||||
@Override
|
||||
public AExperienceRole setLevelToRole(AExperienceLevel level, ARole role) {
|
||||
AExperienceRole byRoleServerAndRole = experienceRoleRepository.findByRole(role);
|
||||
if(byRoleServerAndRole != null) {
|
||||
byRoleServerAndRole.setLevel(level);
|
||||
Optional<AExperienceRole> byRoleServerAndRoleOptional = getRoleInServerOptional(role);
|
||||
AExperienceRole experienceRole;
|
||||
if(byRoleServerAndRoleOptional.isPresent()) {
|
||||
experienceRole = byRoleServerAndRoleOptional.get();
|
||||
experienceRole.setLevel(level);
|
||||
} else {
|
||||
byRoleServerAndRole = AExperienceRole
|
||||
experienceRole = AExperienceRole
|
||||
.builder()
|
||||
.level(level)
|
||||
.roleServer(role.getServer())
|
||||
.role(role)
|
||||
.build();
|
||||
byRoleServerAndRole = experienceRoleRepository.save(byRoleServerAndRole);
|
||||
experienceRole = experienceRoleRepository.save(experienceRole);
|
||||
}
|
||||
return byRoleServerAndRole;
|
||||
return experienceRole;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user