mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-20 12:41:20 +00:00
added command to sync roles for the whole server
added command to remove a role from the experience roles added leaderboard command added rank command fixed missfire configuration for cron jobs (they should not be executed) added ability to configure recovery for jobs added tracking of message count added join listener to automatically give the appropriate role for a joined user added parameter to join listener containing the userInAServer re-added command exception templates added method to create a status message (basically only a single message is returned and expected) added method to edit a single message in a channel to channel service fixed cases in which there are no embeds, but we still used the embed principle of sending messages (only text was send) added more functions to channel service to send messages with moved joined listeners to their separate transaction
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatures;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardModel;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceTrackerService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
|
||||
public static final String LEADERBOARD_POST_EMBED_TEMPLATE = "leaderboard_post";
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private LeaderBoardModelConverter converter;
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Integer page = parameters.size() > 0 ? (Integer) parameters.get(0) : 0;
|
||||
LeaderBoard leaderBoard = experienceTrackerService.findLeaderBoardData(commandContext.getUserInitiatedContext().getServer(), page);
|
||||
LeaderBoardModel leaderBoardModel = (LeaderBoardModel) ContextConverter.fromCommandContext(commandContext, LeaderBoardModel.class);
|
||||
leaderBoardModel.setUserExperiences(converter.fromLeaderBoard(leaderBoard));
|
||||
|
||||
LeaderBoardEntry userRank = experienceTrackerService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
leaderBoardModel.setUserExecuting(converter.fromLeaderBoardEntry(userRank));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(LEADERBOARD_POST_EMBED_TEMPLATE, leaderBoardModel);
|
||||
channelService.sendMessageToEndInTextChannel(messageToSend, commandContext.getChannel());
|
||||
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("page").optional(true).type(Integer.class).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().longHelp("Shows the leaderboard, first 10 places or given page.").usage("leaderboard").build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("leaderboard")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.description("Shows the leaderboard, first 10 places or given page.")
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatures;
|
||||
import dev.sheldan.abstracto.experience.converter.LeaderBoardModelConverter;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.models.templates.RankModel;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceTrackerService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class Rank extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private LeaderBoardModelConverter converter;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelService experienceLevelService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
RankModel rankModel = (RankModel) ContextConverter.fromCommandContext(commandContext, RankModel.class);
|
||||
LeaderBoardEntry userRank = experienceTrackerService.getRankOfUserInServer(commandContext.getUserInitiatedContext().getAUserInAServer());
|
||||
rankModel.setRankUser(converter.fromLeaderBoardEntry(userRank));
|
||||
AUserExperience experienceObj = userRank.getExperience();
|
||||
rankModel.setExperienceToNextLevel(experienceLevelService.calculateExperienceToNextLevel(experienceObj.getCurrentLevel().getLevel(), experienceObj.getExperience()));
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate("rank_post", rankModel);
|
||||
channelService.sendMessageToEndInTextChannel(messageToSend, commandContext.getChannel());
|
||||
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().longHelp("Shows the leaderboard, first 10 places or given page.").usage("rank").build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("rank")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.description("Shows your experience, rank and level on this server.")
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatures;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceTrackerService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class SyncRoles extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
experienceTrackerService.syncUserRolesWithFeedback(commandContext.getUserInitiatedContext().getServer(), commandContext.getUserInitiatedContext().getChannel());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().longHelp("Syncs the role of the current known users with their respective xp.").usage("syncExpRoles").build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("syncExpRoles")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.description("Syncs the roles of the users with their respective experience.")
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatures;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class UnSetRole extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleService experienceRoleService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
Long roleId = (Long) commandContext.getParameters().getParameters().get(0);
|
||||
ARole role = roleManagementService.findRole(roleId);
|
||||
experienceRoleService.unsetRole(role, commandContext.getUserInitiatedContext().getServer());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("roleId").type(Long.class).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().longHelp("Removes the role from the experience tracking").usage("unsetRole <roleId>").build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("unsetRole")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.description("Removes the role from experience tracking")
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package dev.sheldan.abstracto.experience.converter;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class LeaderBoardModelConverter {
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
public List<LeaderBoardEntryModel> fromLeaderBoard(LeaderBoard leaderBoard) {
|
||||
List<LeaderBoardEntryModel> models = new ArrayList<>();
|
||||
leaderBoard.getEntries().forEach(leaderBoardEntry -> {
|
||||
LeaderBoardEntryModel entry = fromLeaderBoardEntry(leaderBoardEntry);
|
||||
models.add(entry);
|
||||
});
|
||||
return models;
|
||||
}
|
||||
|
||||
public LeaderBoardEntryModel fromLeaderBoardEntry(LeaderBoardEntry leaderBoardEntry) {
|
||||
AUserInAServer entryUser = leaderBoardEntry.getExperience().getUser();
|
||||
Member entryMember = botService.getMemberInServer(entryUser.getServerReference().getId(), entryUser.getUserReference().getId());
|
||||
return LeaderBoardEntryModel
|
||||
.builder()
|
||||
.experience(leaderBoardEntry.getExperience())
|
||||
.member(entryMember).rank(leaderBoardEntry.getRank())
|
||||
.rank(leaderBoardEntry.getRank())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class ExperiencePersistingJob extends QuartzJobBean {
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||
HashMap<Long, List<AServer>> runtimeExperience = experienceTrackerService.getRuntimeExperience();
|
||||
log.info("Storing experience");
|
||||
log.info("Persisting experience");
|
||||
Long pastMinute = (Instant.now().getEpochSecond() / 60) - 1;
|
||||
if(runtimeExperience.containsKey(pastMinute)) {
|
||||
experienceTrackerService.handleExperienceGain(runtimeExperience.get(pastMinute));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.abstracto.experience.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.JoinListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.UserManagementService;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatures;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceTrackerService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JoiningUserRoleListener implements JoinListener {
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Override
|
||||
public void execute(Member member, Guild guild, AUserInAServer aUserInAServer) {
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(aUserInAServer);
|
||||
if(userExperience != null) {
|
||||
experienceTrackerService.syncForSingleUser(userExperience);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,28 @@
|
||||
package dev.sheldan.abstracto.experience.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.LeaderBoardEntryResult;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface UserExperienceRepository extends JpaRepository<AUserExperience, Long> {
|
||||
List<AUserExperience> findByUser_ServerReference(AServer server);
|
||||
List<AUserExperience> findTop10ByUser_ServerReferenceOrderByExperienceDesc(AServer server, Pageable pageable);
|
||||
|
||||
@Query(value = "WITH user_experience_ranked AS" +
|
||||
"( " +
|
||||
" SELECT id, experience, experience_role_id, level_id, message_count, ROW_NUMBER() OVER ( ORDER BY experience DESC ) " +
|
||||
" FROM user_experience" +
|
||||
") " +
|
||||
"SELECT rank.id as \"id\", rank.experience as \"experience\", rank.message_count as \"messageCount\", rank.level_id as \"level\", rank.row_number as \"rank\" " +
|
||||
"FROM user_experience_ranked rank " +
|
||||
"where rank.id = :userInServerId", nativeQuery = true)
|
||||
LeaderBoardEntryResult getRankOfUserInServer(@Param("userInServerId") Long id);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceLevelManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -22,4 +23,10 @@ public class ExperienceLevelServiceBean implements ExperienceLevelService {
|
||||
return 5L * (level * level) + 50 * level + 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long calculateExperienceToNextLevel(Integer level, Long currentExperience) {
|
||||
AExperienceLevel nextLevel = experienceLevelManagementService.getLevel(level + 1);
|
||||
return nextLevel.getExperienceNeeded() - currentExperience;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,11 +3,15 @@ package dev.sheldan.abstracto.experience.service;
|
||||
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.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
|
||||
@@ -17,6 +21,12 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
@Autowired
|
||||
private ExperienceLevelManagementService experienceLevelService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Override
|
||||
public void setRoleToLevel(ARole role, Integer level, AServer server) {
|
||||
AExperienceLevel experienceLevel = experienceLevelService.getLevel(level);
|
||||
@@ -24,4 +34,17 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
experienceRoleManagementService.setLevelToRole(experienceLevel, role, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetRole(ARole role, AServer server) {
|
||||
AExperienceRole roleInServer = experienceRoleManagementService.getRoleInServer(role, server);
|
||||
if(roleInServer.getUsers().size() > 0) {
|
||||
roleInServer.getUsers().forEach(userExperience -> {
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRoleForServer(server);
|
||||
roles.removeIf(role1 -> role1.getId().equals(roleInServer.getId()));
|
||||
experienceTrackerService.handleExperienceRoleForUser(userExperience, roles);
|
||||
});
|
||||
}
|
||||
experienceRoleManagementService.unsetRole(roleInServer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
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.core.service.ConfigService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.experience.LeaderBoardEntryResult;
|
||||
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 dev.sheldan.abstracto.experience.models.templates.UserSyncStatusModel;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -42,6 +52,12 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Override
|
||||
public void addExperience(AUserInAServer userInAServer) {
|
||||
Long second = Instant.now().getEpochSecond() / 60;
|
||||
@@ -91,7 +107,7 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
if(userInAServer.getCurrentLevel().getLevel() >= experienceRole.getLevel().getLevel()) {
|
||||
lastRole = experienceRole;
|
||||
} else {
|
||||
return experienceRole;
|
||||
return lastRole;
|
||||
}
|
||||
}
|
||||
return lastRole;
|
||||
@@ -106,14 +122,13 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
log.info("User {} leveled from {} to {}", userInAServer.getUser().getUserReference().getId(), currentLevel, correctLevel);
|
||||
userInAServer.setCurrentLevel(experienceLevelManagementService.getLevel(correctLevel));
|
||||
}
|
||||
userExperienceManagementService.saveUser(userInAServer);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void handleExperienceGain(List<AServer> servers) {
|
||||
servers.forEach(serverExp -> {
|
||||
log.info("Handling experience for server {}", serverExp.getId());
|
||||
log.debug("Handling experience for server {}", serverExp.getId());
|
||||
int minExp = configService.getDoubleValue("minExp", serverExp.getId()).intValue();
|
||||
int maxExp = configService.getDoubleValue("maxExp", serverExp.getId()).intValue();
|
||||
Integer multiplier = configService.getDoubleValue("multiplier", serverExp.getId()).intValue();
|
||||
@@ -124,9 +139,10 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
serverExp.getUsers().forEach(userInAServer -> {
|
||||
Integer gainedExperience = iterator.next();
|
||||
gainedExperience *= multiplier;
|
||||
log.info("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
log.debug("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
increaseExpForUser(userExperience, gainedExperience.longValue(), levels);
|
||||
userExperience.setMessageCount(userExperience.getMessageCount() + 1);
|
||||
handleExperienceRoleForUser(userExperience, roles);
|
||||
});
|
||||
});
|
||||
@@ -135,11 +151,14 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
@Override
|
||||
public void handleExperienceRoleForUser(AUserExperience userExperience, List<AExperienceRole> roles) {
|
||||
AExperienceRole role = calculateRole(userExperience, roles);
|
||||
boolean currentlyHasNoExperienceRole = userExperience.getCurrentExperienceRole() == null;
|
||||
if(role == null) {
|
||||
if(!currentlyHasNoExperienceRole){
|
||||
roleService.removeRoleFromUser(userExperience.getUser(), userExperience.getCurrentExperienceRole().getRole());
|
||||
}
|
||||
return;
|
||||
}
|
||||
boolean currentlyHasNoExperienceRole = userExperience.getCurrentExperienceRole() == null;
|
||||
if(currentlyHasNoExperienceRole || !role.getRole().getId().equals(userExperience.getCurrentExperienceRole().getId())) {
|
||||
if(currentlyHasNoExperienceRole || !role.getRole().getId().equals(userExperience.getCurrentExperienceRole().getRole().getId())) {
|
||||
log.info("User {} gets a new role {}", userExperience.getUser().getUserReference().getId(), role.getRole().getId());
|
||||
if(!currentlyHasNoExperienceRole) {
|
||||
roleService.removeRoleFromUser(userExperience.getUser(), userExperience.getCurrentExperienceRole().getRole());
|
||||
@@ -149,4 +168,78 @@ public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncUserRoles(AServer server) {
|
||||
List<AUserExperience> aUserExperiences = userExperienceManagementService.loadAllUsers(server);
|
||||
log.info("Found {} users to synchronize", aUserExperiences.size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRoleForServer(server);
|
||||
for (int i = 0; i < aUserExperiences.size(); i++) {
|
||||
AUserExperience userExperience = aUserExperiences.get(i);
|
||||
log.debug("Synchronizing {} out of {}", i, aUserExperiences.size());
|
||||
handleExperienceRoleForUser(userExperience, roles);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncUserRolesWithFeedback(AServer server, AChannel channel) {
|
||||
List<AUserExperience> aUserExperiences = userExperienceManagementService.loadAllUsers(server);
|
||||
log.info("Found {} users to synchronize", aUserExperiences.size());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRoleForServer(server);
|
||||
UserSyncStatusModel statusModel = UserSyncStatusModel.builder().currentCount(0).totalUserCount(aUserExperiences.size()).build();
|
||||
MessageToSend status = templateService.renderEmbedTemplate("status_message", statusModel);
|
||||
try {
|
||||
Message statusMessage = messageService.createStatusMessage(status, channel).get();
|
||||
for (int i = 0; i < aUserExperiences.size(); i++) {
|
||||
if((i % 100) == 1) {
|
||||
UserSyncStatusModel incrementalStatusModel = UserSyncStatusModel.builder().currentCount(i).totalUserCount(aUserExperiences.size()).build();
|
||||
status = templateService.renderEmbedTemplate("status_message", incrementalStatusModel);
|
||||
messageService.updateStatusMessage(channel, statusMessage.getIdLong(), status);
|
||||
}
|
||||
log.debug("Synchronizing {} out of {}", i, aUserExperiences.size());
|
||||
AUserExperience userExperience = aUserExperiences.get(i);
|
||||
handleExperienceRoleForUser(userExperience, roles);
|
||||
}
|
||||
UserSyncStatusModel incrementalStatusModel = UserSyncStatusModel.builder().currentCount(aUserExperiences.size()).totalUserCount(aUserExperiences.size()).build();
|
||||
status = templateService.renderEmbedTemplate("status_message", incrementalStatusModel);
|
||||
messageService.updateStatusMessage(channel, statusMessage.getIdLong(), status);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncForSingleUser(AUserExperience userExperience) {
|
||||
log.info("Synchronizing for user {}", userExperience.getUser().getUserReference().getId());
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRoleForServer(userExperience.getUser().getServerReference());
|
||||
handleExperienceRoleForUser(userExperience, roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderBoard findLeaderBoardData(AServer server, Integer page) {
|
||||
List<AUserExperience> experiences = userExperienceManagementService.findLeaderboardUsersPaginated(server, page * 10, (page +1) * 10);
|
||||
log.info("We found {}", experiences.size());
|
||||
List<LeaderBoardEntry> entries = new ArrayList<>();
|
||||
for (int i = 0; i < experiences.size(); i++) {
|
||||
AUserExperience userExperience = experiences.get(i);
|
||||
entries.add(LeaderBoardEntry.builder().experience(userExperience).rank(i + 1).build());
|
||||
}
|
||||
return LeaderBoard.builder().entries(entries).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer) {
|
||||
AUserExperience experience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
LeaderBoardEntryResult rankOfUserInServer = userExperienceManagementService.getRankOfUserInServer(experience);
|
||||
AUserExperience aUserExperience = AUserExperience
|
||||
.builder()
|
||||
.experience(rankOfUserInServer.getExperience())
|
||||
.user(userInAServer)
|
||||
.messageCount(rankOfUserInServer.getMessageCount())
|
||||
.id(userInAServer.getUserInServerId())
|
||||
.currentLevel(experienceLevelManagementService.getLevel(rankOfUserInServer.getLevel()))
|
||||
.build();
|
||||
return LeaderBoardEntry.builder().experience(aUserExperience).rank(rankOfUserInServer.getRank()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,16 @@ public class ExperienceRoleManagementServiceBean implements ExperienceRoleManage
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetRole(AExperienceRole role) {
|
||||
experienceRoleRepository.delete(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceRole getRoleInServer(ARole role, AServer server) {
|
||||
return experienceRoleRepository.findByRoleServerAndRole(server, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceRole> getExperienceRoleForServer(AServer server) {
|
||||
return experienceRoleRepository.findByRoleServer(server);
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
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.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.repository.UserExperienceRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -37,6 +41,7 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
|
||||
AUserExperience userExperience = AUserExperience
|
||||
.builder()
|
||||
.experience(0L)
|
||||
.messageCount(0L)
|
||||
.user(aUserInAServer)
|
||||
.id(aUserInAServer.getUserInServerId())
|
||||
.currentLevel(startingLevel)
|
||||
@@ -49,6 +54,21 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
|
||||
public void saveUser(AUserExperience userExperience) {
|
||||
repository.save(userExperience);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AUserExperience> loadAllUsers(AServer server) {
|
||||
return repository.findByUser_ServerReference(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AUserExperience> findLeaderboardUsersPaginated(AServer aServer, Integer start, Integer end) {
|
||||
return repository.findTop10ByUser_ServerReferenceOrderByExperienceDesc(aServer, PageRequest.of(start, end));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderBoardEntryResult getRankOfUserInServer(AUserExperience userExperience) {
|
||||
return repository.getRankOfUserInServer(userExperience.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ abstracto.scheduling.jobs.experienceJob.clazz=dev.sheldan.abstracto.experience.j
|
||||
abstracto.scheduling.jobs.experienceJob.standAlone=true
|
||||
abstracto.scheduling.jobs.experienceJob.active=true
|
||||
abstracto.scheduling.jobs.experienceJob.cronExpression=30 * * * * ?
|
||||
abstracto.scheduling.jobs.experienceJob.recovery=false
|
||||
|
||||
|
||||
|
||||
abstracto.features.experience=true
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
<#macro userDisplay user>
|
||||
${user.rank} ${user.member.effectiveName} ${user.experience.experience} ${user.experience.currentLevel.level} ${user.experience.messageCount}
|
||||
</#macro>
|
||||
"author": {
|
||||
"name": "${member.effectiveName}",
|
||||
"avatar": "${member.user.effectiveAvatarUrl}"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "
|
||||
Rank | Name | Experience | Level | Messages
|
||||
<#list userExperiences as user>
|
||||
<@userDisplay user=user />
|
||||
</#list>
|
||||
<@userDisplay user=userExecuting />
|
||||
"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "${member.effectiveName}",
|
||||
"avatar": "${member.user.effectiveAvatarUrl}"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "XP",
|
||||
"value": "${rankUser.experience.experience}",
|
||||
"inline": "true"
|
||||
},
|
||||
{
|
||||
"name": "Level",
|
||||
"value": "${rankUser.experience.currentLevel.level}",
|
||||
"inline": "true"
|
||||
},
|
||||
{
|
||||
"name": "Messages",
|
||||
"value": "${rankUser.experience.messageCount}",
|
||||
"inline": "true"
|
||||
},
|
||||
{
|
||||
"name": "XP to next Level",
|
||||
"value": "${experienceToNextLevel}",
|
||||
"inline": "true"
|
||||
},
|
||||
{
|
||||
"name": "Rank",
|
||||
"value": "${rankUser.rank}",
|
||||
"inline": "true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"additionalMessage": "Updating users: ${currentCount}/${totalUserCount}."
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.experience;
|
||||
|
||||
public interface LeaderBoardEntryResult {
|
||||
Long getId();
|
||||
Long getUserInServerId();
|
||||
Long getExperience();
|
||||
Integer getLevel();
|
||||
Long getMessageCount();
|
||||
Integer getRank();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.experience.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LeaderBoard {
|
||||
private List<LeaderBoardEntry> entries;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.experience.models;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LeaderBoardEntry {
|
||||
private AUserExperience experience;
|
||||
private Integer rank;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.sheldan.abstracto.experience.models.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
|
||||
@@ -24,6 +23,8 @@ public class AUserExperience {
|
||||
|
||||
private Long experience;
|
||||
|
||||
private Long messageCount;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "level_id")
|
||||
private AExperienceLevel currentLevel;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class LeaderBoardEntryModel {
|
||||
private AUserExperience experience;
|
||||
private Member member;
|
||||
private Integer rank;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class LeaderBoardModel extends UserInitiatedServerContext {
|
||||
private List<LeaderBoardEntryModel> userExperiences;
|
||||
private LeaderBoardEntryModel userExecuting;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
public class RankModel extends UserInitiatedServerContext {
|
||||
private LeaderBoardEntryModel rankUser;
|
||||
private Long experienceToNextLevel;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.experience.models.templates;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class UserSyncStatusModel {
|
||||
private Integer currentCount;
|
||||
private Integer totalUserCount;
|
||||
}
|
||||
@@ -3,4 +3,5 @@ package dev.sheldan.abstracto.experience.service;
|
||||
public interface ExperienceLevelService {
|
||||
void createExperienceLevel(Integer level, Long experienceNeeded);
|
||||
Long calculateExperienceForLevel(Integer level);
|
||||
Long calculateExperienceToNextLevel(Integer level, Long currentExperience);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
|
||||
|
||||
public interface ExperienceRoleService {
|
||||
void setRoleToLevel(ARole role, Integer level, AServer server);
|
||||
void unsetRole(ARole role, AServer server);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
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;
|
||||
@@ -17,4 +20,9 @@ public interface ExperienceTrackerService {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,7 @@ import java.util.List;
|
||||
public interface ExperienceRoleManagementService {
|
||||
void setLevelToRole(AExperienceLevel level, ARole role, AServer server);
|
||||
void unSetLevelInServer(AExperienceLevel level, AServer server);
|
||||
void unsetRole(AExperienceRole role);
|
||||
AExperienceRole getRoleInServer(ARole role, AServer server);
|
||||
List<AExperienceRole> getExperienceRoleForServer(AServer server);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
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.AUserExperience;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserExperienceManagementService {
|
||||
void setExperienceTo(AUserExperience aUserInAServer, Long experience);
|
||||
AUserExperience findUserInServer(AUserInAServer aUserInAServer);
|
||||
AUserExperience createUserInServer(AUserInAServer aUserInAServer);
|
||||
void saveUser(AUserExperience userExperience);
|
||||
List<AUserExperience> loadAllUsers(AServer server);
|
||||
List<AUserExperience> findLeaderboardUsersPaginated(AServer server, Integer start, Integer end);
|
||||
LeaderBoardEntryResult getRankOfUserInServer(AUserExperience userExperience);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.JoinListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
|
||||
@@ -41,7 +42,7 @@ public class JoinLogger implements JoinListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Member member, Guild guild) {
|
||||
public void execute(Member member, Guild guild, AUserInAServer aUserInAServer) {
|
||||
HashMap<String, Object> parameters = getUserParameter(member.getUser());
|
||||
String text = templateService.renderTemplateWithMap(USER_JOIN_TEMPLATE, parameters);;
|
||||
postTargetService.sendTextInPostTarget(text, JOIN_LOG_TARGET, guild.getIdLong());
|
||||
|
||||
@@ -23,6 +23,7 @@ abstracto.scheduling.jobs.reminderJob.group=utility
|
||||
abstracto.scheduling.jobs.reminderJob.clazz=dev.sheldan.abstracto.utility.jobs.ReminderJob
|
||||
abstracto.scheduling.jobs.reminderJob.standAlone=false
|
||||
abstracto.scheduling.jobs.reminderJob.active=true
|
||||
abstracto.scheduling.jobs.reminderJob.recovery=false
|
||||
|
||||
abstracto.features.starboard=true
|
||||
abstracto.features.remind=true
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -22,6 +25,9 @@ public class JoinListenerBean extends ListenerAdapter {
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) {
|
||||
@@ -30,10 +36,16 @@ public class JoinListenerBean extends ListenerAdapter {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
joinListener.execute(event.getMember(), event.getGuild());
|
||||
AUserInAServer aUserInAServer = userManagementService.loadUser(event.getMember());
|
||||
executeListener(event, joinListener, aUserInAServer);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error("Listener {} failed with exception:", joinListener.getClass().getName(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeListener(@Nonnull GuildMemberJoinEvent event, JoinListener joinListener, AUserInAServer aUserInAServer) {
|
||||
joinListener.execute(event.getMember(), event.getGuild(), aUserInAServer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.exception.ChannelException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildException;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
@@ -7,6 +8,7 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.requests.restaction.MessageAction;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -27,11 +29,16 @@ public class ChannelServiceBean implements ChannelService {
|
||||
|
||||
@Override
|
||||
public void sendTextInAChannel(String text, AChannel channel) {
|
||||
sendTextInAChannelFuture(text, channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendTextInAChannelFuture(String text, AChannel channel) {
|
||||
Guild guild = botService.getInstance().getGuildById(channel.getServer().getId());
|
||||
if (guild != null) {
|
||||
TextChannel textChannel = guild.getTextChannelById(channel.getId());
|
||||
if(textChannel != null) {
|
||||
textChannel.sendMessage(text).queue();
|
||||
return textChannel.sendMessage(text).submit();
|
||||
} else {
|
||||
log.error("Channel {} to post towards was not found in server {}", channel.getId(), channel.getServer().getId());
|
||||
throw new ChannelException(String.format("Channel %s to post to not found.", channel.getId()));
|
||||
@@ -42,6 +49,28 @@ public class ChannelServiceBean implements ChannelService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendEmbedInAChannelFuture(MessageEmbed embed, AChannel channel) {
|
||||
Guild guild = botService.getInstance().getGuildById(channel.getServer().getId());
|
||||
if (guild != null) {
|
||||
TextChannel textChannel = guild.getTextChannelById(channel.getId());
|
||||
if(textChannel != null) {
|
||||
return sendEmbedInAChannelFuture(embed, textChannel);
|
||||
} else {
|
||||
log.error("Channel {} to post towards was not found in server {}", channel.getId(), channel.getServer().getId());
|
||||
throw new ChannelException(String.format("Channel %s to post to not found.", channel.getId()));
|
||||
}
|
||||
} else {
|
||||
log.error("Guild {} was not found when trying to post a message", channel.getServer().getId());
|
||||
throw new GuildException(String.format("Guild %s to post in channel %s was not found.", channel.getServer().getId(), channel.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendEmbedInAChannelFuture(MessageEmbed embed, TextChannel channel) {
|
||||
return channel.sendMessage(embed).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Message>> sendMessageToEndInAChannel(MessageToSend messageToSend, AChannel channel) {
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServer(channel.getServer().getId(), channel.getId());
|
||||
@@ -57,17 +86,15 @@ public class ChannelServiceBean implements ChannelService {
|
||||
List<CompletableFuture<Message>> futures = new ArrayList<>();
|
||||
if(StringUtils.isBlank(messageText)) {
|
||||
messageToSend.getEmbeds().forEach(embed -> {
|
||||
CompletableFuture<Message> messageFuture = textChannel.sendMessage(embed).submit();
|
||||
futures.add(messageFuture);
|
||||
futures.add(sendEmbedInAChannelFuture(embed, textChannel));
|
||||
});
|
||||
} else {
|
||||
MessageAction messageAction = textChannel.sendMessage(messageText);
|
||||
if(messageToSend.getEmbeds().size() > 0) {
|
||||
if(messageToSend.getEmbeds() != null && messageToSend.getEmbeds().size() > 0) {
|
||||
CompletableFuture<Message> messageFuture = messageAction.embed(messageToSend.getEmbeds().get(0)).submit();
|
||||
futures.add(messageFuture);
|
||||
messageToSend.getEmbeds().stream().skip(1).forEach(embed -> {
|
||||
CompletableFuture<Message> nextEmbedFuture = textChannel.sendMessage(embed).submit();
|
||||
futures.add(nextEmbedFuture);
|
||||
futures.add(sendEmbedInAChannelFuture(embed, textChannel));
|
||||
});
|
||||
} else {
|
||||
futures.add(messageAction.submit());
|
||||
@@ -80,4 +107,33 @@ public class ChannelServiceBean implements ChannelService {
|
||||
public Optional<TextChannel> getTextChannelInGuild(Long serverId, Long channelId) {
|
||||
return botService.getTextChannelFromServer(serverId, channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editMessageInAChannel(MessageToSend messageToSend, AChannel channel, Long messageId) {
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServer(channel.getServer().getId(), channel.getId());
|
||||
if(textChannelFromServer.isPresent()) {
|
||||
TextChannel textChannel = textChannelFromServer.get();
|
||||
editMessageInAChannel(messageToSend, textChannel, messageId);
|
||||
} else {
|
||||
throw new ChannelException(String.format("Channel %s was not found.", channel.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editMessageInAChannel(MessageToSend messageToSend, TextChannel channel, Long messageId) {
|
||||
MessageAction messageAction;
|
||||
if(!StringUtils.isBlank(messageToSend.getMessage())) {
|
||||
messageAction = channel.editMessageById(messageId, messageToSend.getMessage());
|
||||
if(messageToSend.getEmbeds() != null && messageToSend.getEmbeds().size() > 0) {
|
||||
messageAction = messageAction.embed(messageToSend.getEmbeds().get(0));
|
||||
}
|
||||
} else {
|
||||
if(messageToSend.getEmbeds() != null && messageToSend.getEmbeds().size() > 0) {
|
||||
messageAction = channel.editMessageById(messageId, messageToSend.getEmbeds().get(0));
|
||||
} else {
|
||||
throw new AbstractoRunTimeException("Message to send did not contain anything to send.");
|
||||
}
|
||||
}
|
||||
messageAction.queue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@ package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.EmoteException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildException;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
@@ -27,6 +29,9 @@ public class MessageServiceBean implements MessageService {
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Override
|
||||
public void addReactionToMessage(String emoteKey, Long serverId, Message message) {
|
||||
Optional<Guild> guildByIdOptional = botService.getGuildById(serverId);
|
||||
@@ -59,4 +64,14 @@ public class MessageServiceBean implements MessageService {
|
||||
public CompletableFuture<Void> deleteMessageInChannelInServer(Long serverId, Long channelId, Long messageId) {
|
||||
return botService.deleteMessage(serverId, channelId, messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> createStatusMessage(MessageToSend messageToSend, AChannel channel) {
|
||||
return channelService.sendMessageToEndInAChannel(messageToSend, channel).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatusMessage(AChannel channel, Long messageId, MessageToSend messageToSend) {
|
||||
channelService.editMessageInAChannel(messageToSend, channel, messageId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ public class PostTargetServiceBean implements PostTargetService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendTextInPostTarget(String text, PostTarget target) {
|
||||
TextChannel textChannelForPostTarget = getTextChannelForPostTarget(target);
|
||||
return textChannelForPostTarget.sendMessage(text).submit();
|
||||
return channelService.sendTextInAChannelFuture(text, target.getChannelReference());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,11 @@ public class UserManagementServiceBean implements UserManagementService {
|
||||
return this.loadUser(member.getGuild().getIdLong(), member.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserInAServer loadUserInServer(Long userInServerId) {
|
||||
return userInServerRepository.getOne(userInServerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserInAServer createUserInServer(Member member) {
|
||||
return this.createUserInServer(member.getGuild().getIdLong(), member.getIdLong());
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Command was not found.
|
||||
@@ -0,0 +1 @@
|
||||
The necessary parameters were not found. A '${class.simpleName}' was expected as '${parameterName}'. Consult help to see the correct syntax.
|
||||
@@ -0,0 +1 @@
|
||||
Insufficient parameters: ${parameterName} was not found.
|
||||
@@ -0,0 +1 @@
|
||||
The parameter ${parameterName} had a too large value: ${actualLength}. The maximum is: ${maximumLength}.
|
||||
@@ -15,7 +15,7 @@ public class FeatureEnabledCondition implements CommandCondition {
|
||||
@Override
|
||||
public ConditionResult shouldExecute(CommandContext context, Command command) {
|
||||
String featureName = command.getFeature();
|
||||
boolean featureFlagValue = false;
|
||||
boolean featureFlagValue = true;
|
||||
String reason = "";
|
||||
if(featureName != null) {
|
||||
featureFlagValue = featureFlagManagementService.getFeatureFlagValue(featureName, context.getGuild().getIdLong());
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
public interface JoinListener extends FeatureAware {
|
||||
void execute(Member member, Guild guild);
|
||||
void execute(Member member, Guild guild, AUserInAServer aUserInAServer);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.core.service;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
import java.util.List;
|
||||
@@ -11,7 +12,12 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface ChannelService {
|
||||
void sendTextInAChannel(String text, AChannel channel);
|
||||
CompletableFuture<Message> sendTextInAChannelFuture(String text, AChannel channel);
|
||||
CompletableFuture<Message> sendEmbedInAChannelFuture(MessageEmbed embed, AChannel channel);
|
||||
CompletableFuture<Message> sendEmbedInAChannelFuture(MessageEmbed embed, TextChannel channel);
|
||||
List<CompletableFuture<Message>> sendMessageToEndInAChannel(MessageToSend messageToSend, AChannel channel);
|
||||
List<CompletableFuture<Message>> sendMessageToEndInTextChannel(MessageToSend messageToSend, TextChannel textChannel);
|
||||
Optional<TextChannel> getTextChannelInGuild(Long serverId, Long channelId);
|
||||
void editMessageInAChannel(MessageToSend messageToSend, AChannel channel, Long messageId);
|
||||
void editMessageInAChannel(MessageToSend messageToSend, TextChannel channel, Long messageId);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface MessageService {
|
||||
void addReactionToMessage(String emoteKey, Long serverId, Message message);
|
||||
CompletableFuture<Void> deleteMessageInChannelInServer(Long serverId, Long channelId, Long messageId);
|
||||
CompletableFuture<Message> createStatusMessage(MessageToSend messageToSend, AChannel channel);
|
||||
void updateStatusMessage(AChannel channel, Long messageId, MessageToSend messageToSend);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ public interface UserManagementService {
|
||||
AUserInAServer loadUser(Long serverId, Long userId);
|
||||
AUserInAServer loadUser(AServer server, AUser user);
|
||||
AUserInAServer loadUser(Member member);
|
||||
AUserInAServer loadUserInServer(Long userInServerId);
|
||||
AUserInAServer createUserInServer(Member member);
|
||||
AUserInAServer createUserInServer(Long guildId, Long userId);
|
||||
AUser createUser(Member member);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class QuartzConfigFactory {
|
||||
|
||||
public CronTrigger createBasicCronTrigger(Date startTime, String cronExpression) {
|
||||
return newTrigger()
|
||||
.withSchedule(cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone("UTC")).withMisfireHandlingInstructionIgnoreMisfires())
|
||||
.withSchedule(cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone("UTC")).withMisfireHandlingInstructionDoNothing())
|
||||
.startAt(startTime)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class SchedulerJobConverter {
|
||||
.active(properties.getActive())
|
||||
.cronExpression(properties.getCronExpression())
|
||||
.clazz(properties.getClazz())
|
||||
.recovery(properties.getRecovery())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,5 @@ public class SchedulerJobProperties {
|
||||
private String cronExpression;
|
||||
private String clazz;
|
||||
private Boolean active;
|
||||
private Boolean recovery;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class SchedulerServiceBean implements SchedulerService {
|
||||
// if its only started by triggers, it needs to be durable
|
||||
boolean recurringJob = isRecurringJob(schedulerJob);
|
||||
jobDetail = scheduleCreator.createJob((Class<? extends QuartzJobBean>) Class.forName(schedulerJob.getClazz()),
|
||||
!recurringJob, context, schedulerJob.getName(), schedulerJob.getGroupName(), false);
|
||||
!recurringJob, context, schedulerJob.getName(), schedulerJob.getGroupName(), schedulerJob.isRecovery());
|
||||
if(recurringJob) {
|
||||
Trigger trigger = scheduleCreator.createBasicCronTrigger(new Date(),
|
||||
schedulerJob.getCronExpression());
|
||||
|
||||
@@ -9,7 +9,7 @@ spring.quartz.properties.org.quartz.threadPool.threadCount=20
|
||||
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
|
||||
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
||||
spring.quartz.properties.org.quartz.jobStore.useProperties=true
|
||||
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000
|
||||
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=45000
|
||||
spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
|
||||
spring.quartz.properties.org.quartz.jobStore.isClustered=false
|
||||
spring.quartz.properties.org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin
|
||||
|
||||
@@ -27,4 +27,6 @@ public class SchedulerJob {
|
||||
private String cronExpression;
|
||||
|
||||
private boolean active;
|
||||
|
||||
private boolean recovery;
|
||||
}
|
||||
@@ -93,7 +93,10 @@ public class TemplateServiceBean implements TemplateService {
|
||||
embedBuilders.forEach(embedBuilder -> embedBuilder.setColor(colorToSet));
|
||||
}
|
||||
|
||||
List<MessageEmbed> embeds = embedBuilders.stream().map(EmbedBuilder::build).collect(Collectors.toList());
|
||||
List<MessageEmbed> embeds = new ArrayList<>();
|
||||
if(embedBuilders.size() > 1 || !embedBuilders.get(0).isEmpty()) {
|
||||
embeds = embedBuilders.stream().map(EmbedBuilder::build).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return MessageToSend.builder()
|
||||
.embeds(embeds)
|
||||
|
||||
Reference in New Issue
Block a user