added javadoc to experience tracking module

changed persistence configuration for entities, so cascade is more correct
changed the way channels get their server assigned
added feature to only change the exp role of a user, if he doesn't already have the new target role
added the name of the needed feature, to the message indicating that a feature has been disabled
updated unsetExpRole to have a status update message, because there might be a lot of users which need a role update
This commit is contained in:
Sheldan
2020-04-23 23:39:05 +02:00
parent 1a74924850
commit cf37d4adef
69 changed files with 929 additions and 260 deletions

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.experience;
public interface LeaderBoardEntryResult {
Long getId();
Long getUserInServerId();
Long getExperience();
Integer getLevel();
Long getMessageCount();
Integer getRank();
}

View File

@@ -6,9 +6,15 @@ import lombok.Setter;
import java.util.List;
/**
* Wrapper object containing a list of {@link LeaderBoardEntry} representing a leaderboard.
*/
@Getter
@Setter
@Builder
public class LeaderBoard {
/**
* List of {@link LeaderBoardEntry} representing the leaderboard.
*/
private List<LeaderBoardEntry> entries;
}

View File

@@ -5,10 +5,19 @@ import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
/**
* Object containing a {@link AUserExperience} object and the respective rank of the user in the guild.
*/
@Getter
@Setter
@Builder
public class LeaderBoardEntry {
/**
* Object representing the current experience status of a user in a guild.
*/
private AUserExperience experience;
/**
* The rank this user has in the respective guild.
*/
private Integer rank;
}

View File

@@ -6,6 +6,9 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Represents an existing level to reach and the total necessary experience needed to reach that level.
*/
@Builder
@Entity
@NoArgsConstructor
@@ -14,7 +17,13 @@ import javax.persistence.Table;
@Getter
@Setter
public class AExperienceLevel {
/**
* The unique level from 0 to as defined in the configuration. Will be created on startup.
*/
@Id
private Integer level;
/**
* The total amount of experience needed for this level.
*/
private Long experienceNeeded;
}

View File

@@ -8,6 +8,10 @@ import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a role which is given when the user reaches a certain level. These roles are configurable per server and
* roles configured in this table are able to be set to a certain level.
*/
@Builder
@Entity
@NoArgsConstructor
@@ -17,28 +21,40 @@ import java.util.List;
@Setter
public class AExperienceRole {
/**
* The abstracto unique id of this experience role.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "level_id")
/**
* Reference to the {@link AExperienceLevel} at which this role is awarded.
*/
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "level_id", nullable = false)
private AExperienceLevel level;
/**
* Reference to the {@link AServer} at which this role is used as an experience role.
*/
@ManyToOne(fetch = FetchType.LAZY)
@Getter
@Setter
@JoinColumn(name = "server_id")
@JoinColumn(name = "server_id", nullable = false)
private AServer roleServer;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "role_id")
/**
* Reference to the actual {@link ARole} being awarded.
*/
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id", nullable = false)
private ARole role;
@OneToMany(
fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
orphanRemoval = true)
/**
* Current list of {@link dev.sheldan.abstracto.core.models.database.AUserInAServer} which were given this role.
*/
@OneToMany(fetch = FetchType.LAZY)
@Builder.Default
@JoinColumn(name = "experience_role_id")
private List<AUserExperience> users = new ArrayList<>();

View File

@@ -4,7 +4,13 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
/**
* Mapping table responsible for tracking the experience and message count of a user in a specific server.
* For easier lookup also contains the current level and the currently awarded experience role.
*/
@Builder
@Entity
@NoArgsConstructor
@@ -12,24 +18,39 @@ import javax.persistence.*;
@Table(name = "user_experience")
@Getter
@Setter
public class AUserExperience {
public class AUserExperience implements Serializable {
/**
* The {@link AUserInAServer} id which is unique for each user in a server.
*/
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@PrimaryKeyJoinColumn
private AUserInAServer user;
/**
* The total amount of experience the user has in the guild
*/
private Long experience;
/**
* The total amount of messages the user has written in the guild resulting in the experience.
*/
private Long messageCount;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "level_id")
/**
* The {@link AExperienceLevel } which the user currently has.
*/
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "level_id", nullable = false)
private AExperienceLevel currentLevel;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
/**
* The {@link AExperienceRole} the user currently has. Can be null.
*/
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "experience_role_id")
private AExperienceRole currentExperienceRole;
}

View File

@@ -0,0 +1,36 @@
package dev.sheldan.abstracto.experience.models.database;
/**
* The object returned from the rank retrieval query.
*/
public interface LeaderBoardEntryResult {
Long getId();
/**
* The {@link dev.sheldan.abstracto.core.models.database.AUserInAServer} id of the user
* @return
*/
Long getUserInServerId();
/**
* The experience of the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer}
*/
Long getExperience();
/**
* The current raw level of the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer}
*/
Integer getLevel();
/**
* The amount of messages tracked by the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer}
*/
Long getMessageCount();
/**
* The current position of the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer} in the leaderboard
* ordered by experience count
*/
Integer getRank();
}

View File

@@ -6,6 +6,11 @@ import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
/**
* Model used in the list of members when rendering the leaderboard command. The reason this is necessary,
* is because we need more than just the {@link AUserExperience} object, we also need the position of the user in this
* guild and the {@link Member} for convenience in the templates.
*/
@Getter
@Setter
@Builder

View File

@@ -7,10 +7,21 @@ import lombok.experimental.SuperBuilder;
import java.util.List;
/**
* Object containing the complete information passed to the leaderboard template. It contains the leaderboard
* information of the requested page of the total users and the leaderboard information of the user executing the
* command.
*/
@Getter
@Setter
@SuperBuilder
public class LeaderBoardModel extends UserInitiatedServerContext {
/**
* List of {@link LeaderBoardEntryModel} containing the information about the users from the requested page.
*/
private List<LeaderBoardEntryModel> userExperiences;
/**
* The {@link LeaderBoardEntryModel} containing the leaderboard information executing the command.
*/
private LeaderBoardEntryModel userExecuting;
}

View File

@@ -5,10 +5,22 @@ import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
/**
* Object containing the provided property to render the rank command template. This includes the
* {@link LeaderBoardEntryModel} object containing the information from the user executing the command, as well as the
* experience needed until next level.
*/
@Getter
@Setter
@SuperBuilder
public class RankModel extends UserInitiatedServerContext {
/**
* The {@link LeaderBoardEntryModel} containing the experience information about the user executing the rank
* command.
*/
private LeaderBoardEntryModel rankUser;
/**
* The necessary experience until the next level up.
*/
private Long experienceToNextLevel;
}

View File

@@ -4,10 +4,21 @@ import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
/**
* Object containing the status update information when the user executes the
* command responsible for synchronizing the users with their experience roles. This is a very barebones
* object as it only contains the current count and the total amount.
*/
@Getter
@Setter
@Builder
public class UserSyncStatusModel {
/**
* The amount of users which already have been processed.
*/
private Integer currentCount;
/**
* The total amount of users for which the experience roles are being synchronized.
*/
private Integer totalUserCount;
}

View File

@@ -0,0 +1,128 @@
package dev.sheldan.abstracto.experience.service;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.experience.models.LeaderBoard;
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
/**
* Service providing the required mechanisms to provide experience tracking.
* This includes manipulations on the {@link AUserExperience} table, container for the runtime experience, synchronizing the
* user in the guild and retrieving {@link LeaderBoard} data.
*/
public interface AUserExperienceService {
/**
* Adds the given {@link AUserInAServer} 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.
* @param userInAServer The {@link AUserInAServer} to be added to the list of users gaining experience
*/
void addExperience(AUserInAServer userInAServer);
/**
* The current representation of the run time epxerience. Basically a HashMap of minutes to a list of {@link AServer}
* containing a list of {@link AUserInAServer} which should gain experience in the minute used as key in the HashMap
* @return
*/
HashMap<Long, List<AServer>> getRuntimeExperience();
/**
* Calculates the appropriate level of the given {@link AUserExperience} according to the given {@link AExperienceLevel}
* configuration.
* @param experience The {@link AUserExperience} to calculate the level for
* @param levels The list of {@link AExperienceLevel} representing the level configuration
* @return The appropriate level of {@link AUserExperience} according to the provided {@link AExperienceLevel} configuration
*/
Integer calculateLevel(AUserExperience experience, List<AExperienceLevel> levels);
/**
* Increases the experience of the provided {@link AUserExperience} object and and calculates the new level according
* to the provided list of {@link AExperienceLevel} used as level configuration
* @param userExperience The {@link AUserExperience} to increase the experience for
* @param levels The list of {@link AExperienceLevel} to be used as level configuration
* @return Whether or not the user changed level
*/
boolean updateUserlevel(AUserExperience userExperience, List<AExperienceLevel> levels);
/**
* Iterates through the given list of {@link AServer} and increases the experience of the users contained in the
* {@link AServer} object, also increments the level and changes the role if necessary.
* This uses the respective configurable max/minExp and multiplier for each {@link AServer} and increases the message count
* of each user by 1.
* @param serverExp The list of {@link AServer} containing the users which get experience
*/
void handleExperienceGain(List<AServer> serverExp);
/**
* Calculates the currently appropriate {@link AExperienceRole} for the given user and updates the role on the
* {@link net.dv8tion.jda.api.entities.Member} and ond the {@link AUserExperience}. Effectively synchronizes the
* state in the server and the database.
* @param userExperience The {@link AUserExperience} object to recalculate the {@link AExperienceRole} for
* @param roles The list of {@link AExperienceRole} used as a role configuration
*/
void updateUserRole(AUserExperience userExperience, List<AExperienceRole> roles);
/**
* Synchronizes the state ({@link AExperienceRole}, {@link net.dv8tion.jda.api.entities.Role})
* of all the users provided in the {@link AServer} object in the {@link AUserExperience}
* and on the {@link net.dv8tion.jda.api.entities.Member} according
* to how much experience the user has. Runs completely in the background.
* @param server The {@link AServer} to update the users for
*/
void syncUserRoles(AServer server);
/**
* Synchronizes the state ({@link AExperienceRole}, {@link net.dv8tion.jda.api.entities.Role})
* of all the users provided in the {@link AServer} object in the {@link AUserExperience}
* and on the {@link net.dv8tion.jda.api.entities.Member} according
* to how much experience the user has. This method provides feedback back to the user in the provided {@link AChannel}
* while the process is going own.
* @param server The {@link AServer} to update users for
* @param channel The {@link AChannel} in which the {@link dev.sheldan.abstracto.experience.models.templates.UserSyncStatusModel}
* should be posted to
*/
void syncUserRolesWithFeedback(AServer server, AChannel channel);
/**
* Recalculates the role of a single user in a server and synchronize the {@link net.dv8tion.jda.api.entities.Role}
* in the {@link net.dv8tion.jda.api.entities.Guild}
* @param userExperience The {@link AUserExperience} to synchronize the role for
*/
void syncForSingleUser(AUserExperience userExperience);
/**
* Loads the desired page of the ordered complete leaderboard from the {@link AServer} and returns the information as a {@link LeaderBoard}
* @param server The {@link AServer} to retrieve the leaderboard for
* @param page The desired page on the leaderboard. The pagesize is 10
* @return The {@link LeaderBoard} containing the {@link LeaderBoardEntry} containing information about the {@link AUserExperience}
* from the desired page
*/
LeaderBoard findLeaderBoardData(AServer server, Integer page);
/**
* Retrieves the {@link LeaderBoardEntry} from a specific {@link AUserInAServer} containing information about the
* gained experience
* @param userInAServer The {@link AUserInAServer} to retrieve the {@link LeaderBoardEntry} for
* @return The {@link LeaderBoardEntry} containing information about gained experience from the given {@link AUserInAServer}
* and the rank of the user in the server
*/
LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer);
/**
* Provides a method to execute an action on a list of {@link AUserExperience} and provide feedback in the given {@link AChannel}
* in the form of {@link dev.sheldan.abstracto.experience.models.templates.UserSyncStatusModel} to be rendered with a certain
* template
* @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
*/
void executeActionOnUserExperiencesWithFeedBack(List<AUserExperience> experiences, AChannel channel, Consumer<AUserExperience> toExecute);
}

View File

@@ -1,7 +1,23 @@
package dev.sheldan.abstracto.experience.service;
/**
* Service responsible for operations on {@link dev.sheldan.abstracto.experience.models.database.AExperienceLevel}
* This includes creating and calculations.
*/
public interface ExperienceLevelService {
void createExperienceLevel(Integer level, Long experienceNeeded);
Long calculateExperienceForLevel(Integer level);
/**
* Creates all the levels up until the given level.
* @param level The max level to create {@link dev.sheldan.abstracto.experience.models.database.AExperienceLevel} for
*/
void createLevelsUntil(Integer level);
/**
* Calculates the required experience until the next level is reached according to the current experience and
* current level.
* @param level The current level to base the calculation of
* @param currentExperience The current experience
* @return The amount of experience required necessary to get to one level higher as currently.
*/
Long calculateExperienceToNextLevel(Integer level, Long currentExperience);
}

View File

@@ -1,9 +1,42 @@
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.experience.models.database.AExperienceLevel;
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import java.util.List;
/**
* Service providing several methods surrounding {@link dev.sheldan.abstracto.experience.models.database.AExperienceRole}.
*/
public interface ExperienceRoleService {
void setRoleToLevel(ARole role, Integer level, AServer server);
void unsetRole(ARole role, AServer server);
/**
* Creates an {@link dev.sheldan.abstracto.experience.models.database.AExperienceRole} according to the given
* parameters
* @param role The {@link ARole} to set the level to
* @param level The level the {@link ARole} should be awareded at
* @param server The {@link AServer} for which this configuration should be done
*/
void setRoleToLevel(ARole role, Integer level, AServer server, AChannel channel);
/**
* Removes the role from the {@link dev.sheldan.abstracto.experience.models.database.AExperienceRole} configuration
* @param role The {@link ARole} to remove from the {@link dev.sheldan.abstracto.experience.models.database.AExperienceRole}
* configuration
* @param server The {@link AServer} for which the {@link ARole} should be removed from the configuration
*/
void unsetRole(ARole role, AServer server, AChannel feedbackChannel);
/**
* Calculates the appropriate {@link AExperienceRole} based on the provided list of {@link AExperienceRole}
* @param userExperience The {@link AUserExperience} containing the level to calculate the {@link AExperienceRole}
* @param roles The role configuration to be used when calculating the appropriate {@link AExperienceRole}
* @return The best matching {@link AExperienceRole} accordign to the experience in the provided {@link AUserExperience}
*/
AExperienceRole calculateRole(AUserExperience userExperience, List<AExperienceRole> roles);
AExperienceLevel getLevelOfNextRole(AExperienceLevel startLevel, AServer server);
}

View File

@@ -1,28 +0,0 @@
package dev.sheldan.abstracto.experience.service;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.experience.models.LeaderBoard;
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import java.util.HashMap;
import java.util.List;
public interface ExperienceTrackerService {
void addExperience(AUserInAServer userInAServer);
HashMap<Long, List<AServer>> getRuntimeExperience();
Integer calculateLevel(AUserExperience userInAServer, List<AExperienceLevel> levels);
AExperienceRole calculateRole(AUserExperience userInAServer, List<AExperienceRole> roles);
void increaseExpForUser(AUserExperience userInAServer, Long experience, List<AExperienceLevel> levels);
void handleExperienceGain(List<AServer> serverExp);
void handleExperienceRoleForUser(AUserExperience userExperience, List<AExperienceRole> roles);
void syncUserRoles(AServer server);
void syncUserRolesWithFeedback(AServer server, AChannel channel);
void syncForSingleUser(AUserExperience userExperience);
LeaderBoard findLeaderBoardData(AServer server, Integer page);
LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer);
}

View File

@@ -4,10 +4,35 @@ import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
import java.util.List;
/**
* Service responsible to create and retrieve {@link AExperienceLevel} objects in the database.
*/
public interface ExperienceLevelManagementService {
/**
* Creates the level referenced by the level and the needed experience in the database.
* @param level The unique level this level should reprsent.
* @param neededExperience The total amount of experience required to reach this level.
* @return A newly created {@link AExperienceLevel} instance.
*/
AExperienceLevel createExperienceLevel(Integer level, Long neededExperience);
/**
* Checks if a {@link AExperienceLevel} level indicated by the level exists in the database. Returns true if it does.
* @param level The integer of the level to check for.
* @return A boolean indicating whether or not the level exists in the database.
*/
boolean levelExists(Integer level);
/**
* Retrieves a {@link AExperienceLevel} according to the given level.
* @param level The level of the wanted {@link AExperienceLevel} to look for
* @return If the level exists, returns the {@link AExperienceLevel}, if it does not exists, returns null.
*/
AExperienceLevel getLevel(Integer level);
AExperienceLevel getLevelClosestTo(Long experience);
/**
* Loads the complete level configuration and returns all found {@link AExperienceLevel} objects from the database.
* @return A list of {@link AExperienceLevel} objects representing the currently active configuration.
*/
List<AExperienceLevel> getLevelConfig();
}

View File

@@ -7,10 +7,47 @@ import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
import java.util.List;
/**
* Service responsible to manage the {@link AExperienceRole} configuration of a server. This contains functionality to
* set/unset a level to a certain role, retrieve {@link AExperienceRole} of a certain role and load all for a given
* server.
*/
public interface ExperienceRoleManagementService {
/**
* Sets the given {@link AExperienceLevel} to the given {@link ARole} in the {@link AServer}. This will create an
* {@link AExperienceRole} instance and store it. If the role was already set in the server, this sets this role to
* the new level.
* @param level The {@link AExperienceLevel} to set the role for
* @param role The {@link ARole} to set to
* @param server The {@link AServer} in which this should happen.
*/
void setLevelToRole(AExperienceLevel level, ARole role, AServer server);
void unSetLevelInServer(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} in the {@link AServer}
* @param level The level to remove the roles for
* @param server The server in which this should happen
*/
void removeAllRoleAssignmentsForLevelInServer(AExperienceLevel level, AServer server);
/**
* Deletes a singular {@link AExperienceRole} directly.
* @param role The {@link AExperienceRole} to delete.
*/
void unsetRole(AExperienceRole role);
/**
* Retrieves the {@link AExperienceRole} which uses the given {@link ARole} in the {@link AServer}
* @param role The {@link ARole} to search for
* @param server The {@link AServer} in which to search in
* @return
*/
AExperienceRole getRoleInServer(ARole role, AServer server);
List<AExperienceRole> getExperienceRoleForServer(AServer server);
/**
* Retrives all {@link AExperienceRole} configured in the given {@link AServer}
* @param server The server to retrieve the list of {@link AExperienceRole} for
* @return A list of {@link AExperienceRole} which are currently configured for the {@link AServer}
*/
List<AExperienceRole> getExperienceRolesForServer(AServer server);
}

View File

@@ -3,19 +3,66 @@ package dev.sheldan.abstracto.experience.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.experience.LeaderBoardEntryResult;
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
import dev.sheldan.abstracto.experience.models.database.LeaderBoardEntryResult;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* Service used to manage the record in the {@link AUserExperience} table
*/
public interface UserExperienceManagementService {
void setExperienceTo(AUserExperience aUserInAServer, Long experience);
/**
* Retrieves the {@link AUserExperience} object for the given {@link AUserInAServer}
* @param aUserInAServer The record in the table referenced by the given {@link AUserInAServer}, if none exists, creates one.
* @return The {@link AUserExperience} object representing the {@link AUserInAServer}
*/
AUserExperience findUserInServer(AUserInAServer aUserInAServer);
/**
* Creates a {@link AUserExperience} object with the default values (0 xp, 0 messages) for the given {@link AUserInAServer} object.
* @param aUserInAServer The {@link AUserInAServer} to create the {@link AUserExperience} object for.
* @return The newly created {@link AUserExperience} object
*/
AUserExperience createUserInServer(AUserInAServer aUserInAServer);
void saveUser(AUserExperience userExperience);
/**
* Loads a list of all {@link AUserExperience} objects for a given {@link AServer}.
* @param server The {@link AServer} to retrieve the list of {@link AUserExperience} for
* @return A list of {@link AUserExperience} objects associated with the given {@link AServer}
*/
List<AUserExperience> loadAllUsers(AServer server);
/**
* Increments the experience of the {@link AUserInAServer} by the given experience and the message count.
* {@link dev.sheldan.abstracto.experience.models.database.AExperienceLevel} or {@link dev.sheldan.abstracto.experience.models.database.AExperienceRole}
* are not changed.
* @param user The {@link AUserInAServer} to increase the experience for
* @param experience The experience amount to increase by
* @param messageCount The amount of messags to increase the count by
* @return The changed/creates {@link AUserExperience} object containing the values.
*/
AUserExperience incrementExpForUser(AUserInAServer user, Long experience, Long messageCount);
/**
* 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
* @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);
/**
* Returns the {@link LeaderBoardEntryResult} of the given {@link AUserExperience}.
* @param userExperience The {@link AUserExperience} to retrieve the information for
* @return The {@link LeaderBoardEntryResult} containing the experience, message count and rank of the given userExperience.
*/
LeaderBoardEntryResult getRankOfUserInServer(AUserExperience userExperience);
/**
* Persists the {@link AUserExperience} in the database. Required when creating it
* @param userExperience The {@link AUserExperience} to persist
*/
void saveUser(AUserExperience userExperience);
}