[AB-60] improving java doc for experience module

This commit is contained in:
Sheldan
2021-03-03 16:35:06 +01:00
parent 821971523e
commit 373dfac001
36 changed files with 390 additions and 244 deletions

View File

@@ -34,6 +34,8 @@ public class DisableExpForRole extends AbstractConditionableCommand {
List<Object> parameters = commandContext.getParameters().getParameters();
ARole role = (ARole) parameters.get(0);
ARole actualRole = roleManagementService.findRole(role.getId());
// as we mange experience disabled roles via the existence of them in a table, we should not do anything
// in case it is used a second time as a disabled experience role
if(!disabledExpRoleManagementService.isExperienceDisabledForRole(actualRole)) {
disabledExpRoleManagementService.setRoleToBeDisabledForExp(actualRole);
}

View File

@@ -33,6 +33,7 @@ public class EnableExpForRole extends AbstractConditionableCommand {
public CommandResult execute(CommandContext commandContext) {
ARole role = (ARole) commandContext.getParameters().getParameters().get(0);
ARole actualRole = roleManagementService.findRole(role.getId());
// If its not disabled for the role, we can remove it
if(disabledExpRoleManagementService.isExperienceDisabledForRole(actualRole)) {
disabledExpRoleManagementService.removeRoleToBeDisabledForExp(actualRole);
}

View File

@@ -19,7 +19,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* Command to enable experience again for a member
* Command to enable experience gain for a member
*/
@Component
public class EnableExpGain extends AbstractConditionableCommand {

View File

@@ -3,6 +3,9 @@ package dev.sheldan.abstracto.experience.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* Config file containing the default configurations related to experience
*/
@Configuration
@PropertySource("classpath:experience-config.properties")
public class ExperienceConfig {

View File

@@ -15,7 +15,7 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Converter used to convert from {@link LeaderBoard} to a list of {@link LeaderBoardEntryModel}
* Converter used to convert from {@link LeaderBoard leaderBoard} to a list of {@link LeaderBoardEntryModel leaderBoardEntryModels}
*/
@Component
@Slf4j
@@ -25,15 +25,15 @@ public class LeaderBoardModelConverter {
private MemberService memberService;
/**
* Converts the complete {@link LeaderBoard} into a list of {@link LeaderBoardEntryModel} which contain additional
* information available for rendering the leader board ({@link Member} reference and more)
* @param leaderBoard The {@link LeaderBoard} object to be converted
* @return The list of {@link LeaderBoardEntryModel} which contain the fully fledged information provided to the
* Converts the complete {@link LeaderBoard leaderBoard} into a list of {@link LeaderBoardEntryModel leaderbaordEntryModels} which contain additional
* information available for rendering the leader board ({@link Member member} reference and more)
* @param leaderBoard The {@link LeaderBoard leaderBoard} object to be converted
* @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<>();
log.trace("Converting {} entries to a list of leaderbord entries.", leaderBoard.getEntries().size());
log.trace("Converting {} entries to a list of leaderboard entries.", leaderBoard.getEntries().size());
leaderBoard.getEntries().forEach(leaderBoardEntry -> {
CompletableFuture<LeaderBoardEntryModel> entry = fromLeaderBoardEntry(leaderBoardEntry);
models.add(entry);
@@ -42,10 +42,10 @@ public class LeaderBoardModelConverter {
}
/**
* Converts the given {@link LeaderBoardEntry} to a {@link LeaderBoardEntryModel}, which provides a reference to the
* {@link Member} object of the given {@link AUserInAServer} for convenience in the template
* @param leaderBoardEntry The {@link LeaderBoardEntry} to be converted
* @return The {@link LeaderBoardEntryModel} accompanied with the {@link Member} reference, might be null, if the
* 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) {

View File

@@ -18,7 +18,7 @@ import java.util.Map;
/**
* This {@link QuartzJobBean} is executed regularly and calls the the {@link AUserExperienceService}
* This {@link QuartzJobBean job} is executed regularly and calls the the {@link AUserExperienceService service}
* store the tracked experience from runtime. This job also cleans up the already processed entries in the runtime
* experience.
*/

View File

@@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* This {@link MessageReceivedListener} is responsible to execute the {@link AUserExperienceService} in order to track
* This {@link MessageReceivedListener listener} is responsible to execute the {@link AUserExperienceService service} in order to track
* that a certain user has send a message, and experience should be awarded.
*/
@Component

View File

@@ -16,8 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* If a user joins, this {@link JoinListener} retrieves the previously stored {@link AUserExperience} and gives the
* {@link Member} the necessary {@link net.dv8tion.jda.api.entities.Role} according to the current configuration
* If a {@link Member member} joins, this {@link JoinListener listener} retrieves the previously stored {@link AUserExperience experience} and gives the
* member the necessary {@link net.dv8tion.jda.api.entities.Role role} according to the current configuration, if any
*/
@Component
@Slf4j

View File

@@ -9,15 +9,28 @@ import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Repository to manage the access to the table managed by {@link ADisabledExpRole}
* Repository to manage the access to the table managed by {@link ADisabledExpRole disabledRole}
*/
@Repository
public interface DisabledExpRoleRepository extends JpaRepository<ADisabledExpRole, Long> {
/**
* Determines if there exists a {@link ADisabledExpRole disabledExpRole} which is defined by the given {@link ARole role}
* @param role The {@link ARole role} to search for
* @return Whether or not a role {@link ADisabledExpRole disabledExpRole} for this {@link ARole role} eixsts
*/
boolean existsByRole(ARole role);
ADisabledExpRole findByRole(ARole role);
/**
* Deletes the {@link ADisabledExpRole disabledExpRole} defined for this {@link ARole role}, if there is any.
* @param role The {@link ARole} to delete the {@link ADisabledExpRole disabledExpRole} for
*/
void deleteByRole(ARole role);
/**
* Returns all {@link ADisabledExpRole disabledExpRoles} for the given {@link AServer server}
* @param server The {@link AServer server} to retrieve the {@link ADisabledExpRole disabledExpRoles} for
* @return The list of {@link ADisabledExpRole disabledExpRoles} found, can be empty
*/
List<ADisabledExpRole> getByRole_Server(AServer server);
}

View File

@@ -10,18 +10,9 @@ import java.util.List;
import java.util.Optional;
/**
* Repository to manage the access to the table managed by {@link AExperienceLevel}
* Repository to manage the access to the table managed by {@link AExperienceLevel experienceLevel}
*/
@Repository
public interface ExperienceLevelRepository extends JpaRepository<AExperienceLevel, Integer> {
@NotNull
@Override
Optional<AExperienceLevel> findById(@NonNull Integer aLong);
@Override
boolean existsById(@NonNull Integer aLong);
@NotNull
@Override
List<AExperienceLevel> findAll();
}

View File

@@ -13,34 +13,31 @@ import java.util.List;
import java.util.Optional;
/**
* Repository to manage the access to the table managed by {@link AExperienceRole}
* Repository to manage the access to the table managed by {@link AExperienceRole experienceRole}
*/
@Repository
public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole, Long> {
/**
* Finds the {@link AExperienceRole} of the given {@link AServer} and {@link ARole}
* @param role The {@link ARole} to filter for
* @return The {@link AExperienceRole} found or null if the query did not return any results
* Finds the {@link AExperienceRole experienceRole} of the given {@link AServer server} and {@link ARole role}
* @param role The {@link ARole role} to filter for
* @return The {@link AExperienceRole experienceRole} found or null if the query did not return any results
*/
Optional<AExperienceRole> findByRole(ARole role);
/**
* Finds a list of {@link AExperienceRole} (if there are multiple ones, because of misconfiguration) of the given
* {@link AExperienceLevel} and {@link AServer}
* @param level The {@link AExperienceLevel} to search for
* @param server The {@link AServer} to search for
* @return The list of {@link AExperienceRole} found by the given parameters
* Finds a list of {@link AExperienceRole experienceRoles} (if there are multiple ones, because of misconfiguration) of the given
* {@link AExperienceLevel experienceLevel} and {@link AServer server}
* @param level The {@link AExperienceLevel experienceLevel} to search for
* @param server The {@link AServer server} to search for
* @return The list of {@link AExperienceRole experienceRole} found by the given parameters
*/
List<AExperienceRole> findByLevelAndRoleServer(AExperienceLevel level, AServer server);
/**
* Finds all {@link AExperienceRole} of the given {@link AServer}
* @param server The {@link AServer} to load the list of {@link AExperienceRole} for
* @return A list of {@link AExperienceRole} configured to be used on the given {@link AServer}
* Finds all {@link AExperienceRole experienceRoles} of the given {@link AServer server}
* @param server The {@link AServer server} to load the list of {@link AExperienceRole experienceRoles} for
* @return A list of {@link AExperienceRole experienceRoles} configured to be used on the given {@link AServer server}
*/
List<AExperienceRole> findByRoleServer(AServer server);
@NotNull
@Override
Optional<AExperienceRole> findById(@NonNull Long aLong);
}

View File

@@ -15,33 +15,34 @@ import java.util.List;
import java.util.Optional;
/**
* Repository to manage the access to the table managed by {@link AUserExperience}
* Repository to manage the access to the table managed by {@link AUserExperience userExperience}
*/
@Repository
public interface UserExperienceRepository extends JpaRepository<AUserExperience, Long> {
/**
* Finds all {@link AUserExperience} of the given {@link AServer}
* @param server The {@link AServer} to retrieve ethe {@link AUserExperience} for
* @return A complete list of {@link AUserExperience} of the given {@link AServer}
* Finds all {@link AUserExperience userExperience} of the given {@link AServer server}
* @param server The {@link AServer server} to retrieve the {@link AUserExperience userExperience} for
* @return A complete list of {@link AUserExperience} of the given {@link AServer server}
*/
List<AUserExperience> findByUser_ServerReference(AServer server);
/**
* Retrieves the {@link AUserExperience} ordered by experience, and applies the {@link Pageable} to only filter out certain pages.
* @param server The {@link AServer} to retrieve the {@link AUserExperience} information for
* @param pageable A {@link Pageable} object to indicate the pages which should be retrieved, page size is 10
* @return A list of {@link AUserExperience} of the given {@link AServer} ordered by the experience of the users, paginated by the given
* Retrieves the {@link AUserExperience userExperience} ordered by experience, and applies the {@link Pageable pageable} to only filter out certain pages.
* @param server The {@link AServer server} to retrieve the {@link AUserExperience userExperience} information for
* @param pageable A {@link Pageable pageable} object to indicate the pages which should be retrieved, page size is 10
* @return A list of {@link AUserExperience userExperience} of the given {@link AServer server} ordered by the experience of the users, paginated by the given
* configuration
*/
List<AUserExperience> findTop10ByUser_ServerReferenceOrderByExperienceDesc(AServer server, Pageable pageable);
/**
* This returns the {@link LeaderBoardEntryResult} object containing the information about the rank of a user in a server.
* This returns the {@link LeaderBoardEntryResult entryResult} object containing the information about the rank of a user in a server.
* This query selects all the experience entries and returns the one associated with the provided user.
* We need to select all of them, in order to find the rank of the member in the server
* @param id The {@link dev.sheldan.abstracto.core.models.database.AUserInAServer} id to search for
* @return the {@link LeaderBoardEntryResult} of this {@link dev.sheldan.abstracto.core.models.database.AUserInAServer}
* @param id The ID of an {@link dev.sheldan.abstracto.core.models.database.AUserInAServer userInAServer} search for
* @param serverId The ID of the {@link AServer server} for which we are retrieving the experience
* @return The {@link LeaderBoardEntryResult result} of this {@link dev.sheldan.abstracto.core.models.database.AUserInAServer userInAServer}
* containing rank and experience information
*/
@Query(value = "WITH user_experience_ranked AS" +
@@ -54,7 +55,4 @@ public interface UserExperienceRepository extends JpaRepository<AUserExperience
"WHERE rank.id = :userInServerId", nativeQuery = true)
LeaderBoardEntryResult getRankOfUserInServer(@Param("userInServerId") Long id, @Param("serverId") Long serverId);
@NotNull
@Override
Optional<AUserExperience> findById(@NonNull Long aLong);
}

View File

@@ -88,10 +88,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
@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
*/
@Override
public void addExperience(AUserInAServer userInAServer) {
runTimeExperienceService.takeLock();
@@ -124,14 +120,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
}
/**
* Calculates the level of the given {@link AUserExperience} according to the given {@link AExperienceLevel} list
* @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(List<AExperienceLevel> levels, Long experienceCount) {
AExperienceLevel lastLevel = levels.get(0);
@@ -160,14 +148,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
return false;
}
/**
* Calculates the actually gained experience for every user in the given servers and adds them to the users.
* This method only actually increases the message count, and calls other methods for experience gain
* and role change.
* Loads the level and role configuration for each server and sorts them for them to be used.
* Only actually updates the role, if the user also changed level.
* @param servers The list of {@link AServer} containing the user which need to gain experience
*/
@Transactional
@Override
public CompletableFuture<Void> handleExperienceGain(List<ServerExperience> servers) {
@@ -249,7 +229,21 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
);
}
/**
* Calculates the appropriate {@link AExperienceRole experienceRole} based on the current level and awards the referenced the {@link AUserInAServer userinAServer}
* the {@link net.dv8tion.jda.api.entities.Role role}. If the user already left the guild, this will not award a {@link net.dv8tion.jda.api.entities.Role}, but just
* return the instance in order to be persisted
* @param aUserInAServer The {@link AUserInAServer userInAServer} which does not have a {@link AUserExperience userExperience} object,
* therefore we need to calculate the appropriate role and award the role
* @param roles A list of {@link AExperienceRole experienceRoles} representing the configuration which is used to calculate the appropriate
* {@link AExperienceRole experienceRole}
* @param currentLevel The current level of the user which was reached.
* @return A {@link CompletableFuture future} containing the {@link RoleCalculationResult result} of the role calculation, which completes after the user has been awarded the role.
*/
private CompletableFuture<RoleCalculationResult> applyInitialRole(AUserInAServer aUserInAServer, List<AExperienceRole> roles, Integer currentLevel) {
// we are in the process of attributing experience, which means the member should have send a message, therefore is in the case
// if the member is actually _not_ in the guild anymore (would mean, joined, send a message, and left immediately) this check is required
// this is backed by the cache
if(!memberService.isUserInGuild(aUserInAServer)) {
log.trace("User {} is not in server {} anymore. No role calculation done.", aUserInAServer.getUserInServerId(), aUserInAServer.getServerReference().getId());
return CompletableFuture.completedFuture(RoleCalculationResult
@@ -279,8 +273,15 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
.build());
}
/**
* Persists the list of {@link ExperienceGainResult results} in the database. If the creation of {@link AUserExperience userExperience} object was requested,
* this will happen here, also the correct level is selected
* @param resultFutures A list of {@link ExperienceGainResult results} which define what should be changed for the given {@link AUserExperience userExperience} object:
* The level, experience, experienceRole, message account could change, or the object could not even exist ({@link ExperienceGainResult#createUserExperience})
*/
@Transactional
public void persistExperienceChanges(List<ExperienceGainResult> resultFutures) {
// we do have the _value_ of the level, but we require the actual instance
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
log.info("Storing {} experience gain results.", resultFutures.size());
HashMap<Long, List<AExperienceRole>> serverRoleMapping = new HashMap<>();
@@ -295,13 +296,18 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
}
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 matching the calculation result {} could be found.", userExperience.getUser().getUserReference().getId(), experienceGainResult.getNewLevel());
// only search the levels if the level changed, or if there is no level currently set
boolean userExperienceHasLevel = userExperience.getCurrentLevel() != null;
if(!userExperienceHasLevel || !userExperience.getCurrentLevel().getLevel().equals(experienceGainResult.getNewLevel())) {
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 matching the calculation result {} could be found.", userExperience.getUser().getUserReference().getId(), experienceGainResult.getNewLevel());
}
}
AServer server = user.getServerReference();
// "Caching" the experience roles for this server
if(!serverRoleMapping.containsKey(server.getId())) {
serverRoleMapping.put(server.getId(), experienceRoleManagementService.getExperienceRolesForServer(server));
}
@@ -316,14 +322,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
});
}
/**
* Calculates the appropriate level of the user and changes the role, if the {@link AExperienceLevel} changes.
* This changes the config in the database, and also gives the {@link net.dv8tion.jda.api.entities.Member} the new
* {@link net.dv8tion.jda.api.entities.Role}. If the user does not warrant an {@link AExperienceRole},
* this method also removes it. The role is only changed, if the user does not have
* @param userExperience The {@link AUserExperience} object to recalculate the {@link AExperienceRole} for
* @param roles The list of {@link AExperienceRole} used as a role configuration
*/
@Override
public CompletableFuture<RoleCalculationResult> updateUserRole(AUserExperience userExperience, List<AExperienceRole> roles, Integer currentLevel) {
AUserInAServer user = userExperience.getUser();
@@ -390,11 +388,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
});
}
/**
* Synchronizes the {@link net.dv8tion.jda.api.entities.Role} of all {@link net.dv8tion.jda.api.entities.Member} in
* the given {@link AServer}. This might take a long time to complete, because there are a lot of role changes.
* @param server The {@link AServer} to update the users for
*/
@Override
public List<CompletableFuture<RoleCalculationResult>> syncUserRoles(AServer server) {
List<CompletableFuture<RoleCalculationResult>> results = new ArrayList<>();
@@ -409,11 +402,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
return results;
}
/**
* Synchronizes the roles of all the users and provides feedback to the user executing
* @param server The {@link AServer} to update users for
* @param channelId The ID of the channel in which the {@link dev.sheldan.abstracto.experience.models.templates.UserSyncStatusModel} should be posted to
*/
@Override
public CompletableFuture<Void> syncUserRolesWithFeedback(AServer server, Long channelId) {
AChannel channel = channelManagementService.loadChannel(channelId);
@@ -432,6 +420,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
*/
@Transactional
public void syncRolesInStorage(List<RoleCalculationResult> results) {
HashMap<Long, AExperienceRole> experienceRoleHashMap = new HashMap<>();
results.forEach(result -> {
if(result != null) {
AUserInAServer user = userInServerManagementService.loadOrCreateUser(result.getUserInServerId());
@@ -439,7 +428,13 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
log.trace("Updating experience role for {} in server {} to {}", user.getUserInServerId(), user.getServerReference().getId(), result.getExperienceRoleId());
if(result.getExperienceRoleId() != null) {
log.trace("User experience {} gets new experience role with id {}.", userExperience.getId(), result.getExperienceRoleId());
AExperienceRole role = experienceRoleManagementService.getExperienceRoleById(result.getExperienceRoleId());
AExperienceRole role;
if(!experienceRoleHashMap.containsKey(result.getExperienceRoleId())) {
role = experienceRoleManagementService.getExperienceRoleById(result.getExperienceRoleId());
experienceRoleHashMap.put(result.getExperienceRoleId(), role);
} else {
role = experienceRoleHashMap.get(result.getExperienceRoleId());
}
userExperience.setCurrentExperienceRole(role);
} else {
log.trace("User experience {} does not get a user experience role.", userExperience.getId());
@@ -449,12 +444,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
});
}
/**
* Executes the given {@link Consumer} on each of the experiences and provides feedback in the given AChannel in the form of a status message
* @param experiences The list of {@link AUserExperience} to be working on
* @param channel The {@link AChannel} used to provide feedback to the user
* @param toExecute The {@link Consumer} which should be executed on each element of the passed list
*/
@Override
public CompletableFutureList<RoleCalculationResult> executeActionOnUserExperiencesWithFeedBack(List<AUserExperience> experiences, AChannel channel, Function<AUserExperience, CompletableFuture<RoleCalculationResult>> toExecute) {
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
@@ -491,15 +480,18 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
userExperience.setExperienceGainDisabled(false);
}
/**
* Renders a {@link MessageToSend messageToSend} to be used as a status message for the ongoing user synchronization
* @param current The amount of users which have been synced
* @param total The total amount of users which will be synced
* @param serverId The ÍD of the {@link AServer server} for which this synchronization is being executed
* @return A {@link MessageToSend messageToSend} which will be used to inform the user executing the synchronization about the new situation
*/
private MessageToSend getUserSyncStatusUpdateModel(Integer current, Integer total, Long serverId) {
UserSyncStatusModel statusModel = UserSyncStatusModel.builder().currentCount(current).totalUserCount(total).build();
return templateService.renderEmbedTemplate("user_sync_status_message", statusModel, serverId);
}
/**
* Retrieves the role configuration and executes the method responsible to sync the experience role of the user
* @param userExperience The {@link AUserExperience} to synchronize the role for
*/
@Override
public CompletableFuture<RoleCalculationResult> syncForSingleUser(AUserExperience userExperience) {
AUserInAServer user = userExperience.getUser();
@@ -508,12 +500,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
return updateUserRole(userExperience, roles, userExperience.getLevelOrDefault());
}
/**
* Retrieves the leader board data for the given page of the given server
* @param server The {@link AServer} to retrieve the leader board for
* @param page The desired page on the leader board. The page size is 10
* @return The {@link LeaderBoard} containing all necessary information concerning the leader board
*/
@Override
public LeaderBoard findLeaderBoardData(AServer server, Integer page) {
if(page <= 0) {
@@ -532,11 +518,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
return LeaderBoard.builder().entries(entries).build();
}
/**
* Builds an {@link AUserExperience} and loads the appropriate rank of the passed {@link AUserInAServer}
* @param userInAServer The {@link AUserInAServer} to retrieve the {@link LeaderBoardEntry} for
* @return The {@link LeaderBoardEntry} representing one single row in the leader board
*/
@Override
public LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer) {
log.trace("Retrieving rank for {}", userInAServer.getUserReference().getId());

View File

@@ -61,6 +61,12 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
);
}
/**
* Removes all previous defined {@link AExperienceRole experienceRoles} from the given leve 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
*/
@Transactional
public void unsetRoleInDb(Integer level, Long roleId) {
log.info("Unsetting role {} from level {}.", roleId, level);
@@ -103,21 +109,22 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
}
}
/**
* Stores the changed experience roles for all of the {@link AUserExperience userExperiences} which are referenced in the list of
* {@link RoleCalculationResult results}. This is only executed after a role is being "unset", which means, we also
* 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
*/
@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.getRoleInServer(roleId);
AExperienceRole roleInServer = experienceRoleManagementService.getExperienceRoleById(roleId);
experienceRoleManagementService.unsetRole(roleInServer);
userExperienceService.syncRolesInStorage(results.getObjects());
}
/**
* 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(List<AExperienceRole> roles, Integer currentLevel) {
if(roles == null || roles.isEmpty()) {

View File

@@ -13,6 +13,10 @@ import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Responsible for maintaining the data structure containing the IDs of {@link dev.sheldan.abstracto.core.models.database.AUserInAServer}
* for which experience should be given, because they sent messages on their respective servers
*/
@Component
public class RunTimeExperienceService {
@@ -31,10 +35,16 @@ public class RunTimeExperienceService {
return runtimeExperience;
}
/**
* Acquires the lock of the runtime experience data structure. Operations on it should only be done, while holding the lock
*/
public void takeLock() {
lock.lock();
}
/**
* Releases the lock again, and allows others to take the lock, if they want to modify the data structure.
*/
public void releaseLock() {
lock.unlock();
}

View File

@@ -16,12 +16,18 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Optional;
/**
* This condition evaluates whether or not a given {@link AUserExperience userExperience}, defined by the ID of {@link AUserInAServer userInAServer}
* has at least the given level.
*/
@Component
@Slf4j
public class HasLevelCondition implements SystemCondition {
public static final String USER_ID_VARIABLE = "userId";
public static final String USER_IN_SERVER_ID_VARIABLE_KEY = "userId";
public static final String LEVEL_VARIABLE = "level";
public static final String HAS_LEVEL_CONDITION_KEY = "HAS_LEVEL";
@Autowired
private UserExperienceManagementService userExperienceManagementService;
@@ -31,10 +37,10 @@ public class HasLevelCondition implements SystemCondition {
@Override
public boolean checkCondition(ConditionContextInstance conditionContext) {
HashMap<String, Object> parameters = conditionContext.getParameters();
Long userId = (Long) parameters.get(USER_ID_VARIABLE);
Long userInServerId = (Long) parameters.get(USER_IN_SERVER_ID_VARIABLE_KEY);
Integer level = (Integer) parameters.get(LEVEL_VARIABLE);
log.info("Evaluating has level condition.");
Optional<AUserInAServer> userInServerOptional = userInServerManagementService.loadUserOptional(userId);
Optional<AUserInAServer> userInServerOptional = userInServerManagementService.loadUserOptional(userInServerId);
if(userInServerOptional.isPresent()) {
AUserInAServer userInServer = userInServerOptional.get();
log.info("Evaluating has level condition for user {} in server {} with level {}.",
@@ -49,13 +55,13 @@ public class HasLevelCondition implements SystemCondition {
@Override
public String getConditionName() {
return "HAS_LEVEL";
return HAS_LEVEL_CONDITION_KEY;
}
@Override
public ConditionContext getExpectedContext() {
ConditionContextVariable userIdVariable = ConditionContextVariable.builder().name(USER_ID_VARIABLE).type(Long.class).build();
ConditionContextVariable userIdVariable = ConditionContextVariable.builder().name(USER_IN_SERVER_ID_VARIABLE_KEY).type(Long.class).build();
ConditionContextVariable levelVariable = ConditionContextVariable.builder().name(LEVEL_VARIABLE).type(Integer.class).build();
return ConditionContext.builder().expectedVariables(Arrays.asList(userIdVariable, levelVariable)).build();
return ConditionContext.builder().requiredVariables(Arrays.asList(userIdVariable, levelVariable)).build();
}
}

View File

@@ -44,6 +44,7 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
@Override
public AExperienceRole getRoleInServer(ARole role) {
// TODO throw different exception
return this.getRoleInServerOptional(role).orElseThrow(AbstractoRunTimeException::new);
}
@@ -52,12 +53,6 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
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);
@@ -65,6 +60,7 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
@Override
public AExperienceRole getExperienceRoleById(Long experienceRoleId) {
// TODO throw different exception
return getExperienceRoleByIdOptional(experienceRoleId).orElseThrow(() -> new AbstractoRunTimeException("Experience role not found"));
}

View File

@@ -42,11 +42,6 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
return findByUserInServerIdOptional(userInServerId).orElseThrow(() -> new UserInServerNotFoundException(userInServerId));
}
/**
* Initializes the {@link AUserExperience} with default values the following: 0 experience, 0 messages and experience gain enabled
* @param aUserInAServer The {@link AUserInAServer} to create the {@link AUserExperience} object for.
* @return The created/changed {@link AUserExperience} object
*/
@Override
public AUserExperience createUserInServer(AUserInAServer aUserInAServer) {
log.info("Creating user experience for user {} in server {}.", aUserInAServer.getUserReference().getId(),aUserInAServer.getServerReference().getId());