mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-15 12:10:21 +00:00
added experience tracking and automatic role assigning at given levels
includes: set role command to set a role to a given level (it clears out previous levels) automatic level config generation on startup min/max/multiplier configuration job to persist the xp of the previous minute added delayed scheduler start, so that events have a discord context in order to function added role listener to automatically add and mark roles when they are created/deleted fixed user in a server not being created correctly added role service to give users role given by id added server reference to role
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>experience-tracking-impl</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.sheldan.abstracto.experience.commands;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.config.ModuleInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.ModuleInterface;
|
||||
|
||||
public class ExperienceModule implements ModuleInterface {
|
||||
|
||||
public static final String EXPERIENCE = "utility";
|
||||
|
||||
@Override
|
||||
public ModuleInfo getInfo() {
|
||||
return ModuleInfo.builder().name(EXPERIENCE).description("Module containing commands related to experience tracking.").build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentModule() {
|
||||
return "default";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
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 SetRole extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleService experienceRoleService;
|
||||
|
||||
@Autowired
|
||||
private RoleManagementService roleManagementService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
Integer level = (Integer) commandContext.getParameters().getParameters().get(0);
|
||||
Long roleId = (Long) commandContext.getParameters().getParameters().get(1);
|
||||
ARole role = roleManagementService.findRole(roleId);
|
||||
experienceRoleService.setRoleToLevel(role, level, commandContext.getUserInitiatedContext().getServer());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("level").type(Integer.class).build());
|
||||
parameters.add(Parameter.builder().name("roleId").type(Long.class).build());
|
||||
HelpInfo helpInfo = HelpInfo.builder().longHelp("Sets the role to a certain level").usage("setRole <level> <roleId>").build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("setRole")
|
||||
.module(ExperienceModule.EXPERIENCE)
|
||||
.description("Sets the role to a certain level")
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.experience.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(prefix = "abstracto.experience")
|
||||
public class ExperienceConfig {
|
||||
private Integer minExp;
|
||||
private Integer maxExp;
|
||||
private Integer multiplier;
|
||||
private Integer maxLvl;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.abstracto.experience.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.ConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ExperienceConfigListener implements ServerConfigListener {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ExperienceConfig experienceConfig;
|
||||
|
||||
@Autowired
|
||||
private ConfigService service;
|
||||
|
||||
@Override
|
||||
public void updateServerConfig(AServer server) {
|
||||
log.info("Setting up experience for {}", server.getId());
|
||||
service.createDoubleValueIfNotExist("minExp", server.getId(), experienceConfig.getMinExp().doubleValue());
|
||||
service.createDoubleValueIfNotExist("maxExp", server.getId(), experienceConfig.getMaxExp().doubleValue());
|
||||
service.createDoubleValueIfNotExist("multiplier", server.getId(), experienceConfig.getMultiplier().doubleValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.sheldan.abstracto.experience.config;
|
||||
|
||||
public class ExperienceFeatures {
|
||||
public static String EXPERIENCE = "experience";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dev.sheldan.abstracto.experience.config;
|
||||
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ExperienceLevelLoader {
|
||||
|
||||
@Autowired
|
||||
private ExperienceConfig experienceConfig;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelService experienceLevelService;
|
||||
|
||||
@EventListener
|
||||
public void handleContextRefreshEvent(ContextRefreshedEvent ctxStartEvt) {
|
||||
Integer maxLevel = experienceConfig.getMaxLvl();
|
||||
Long experience = 0L;
|
||||
experienceLevelService.createExperienceLevel(0, 0L);
|
||||
for (int i = 1; i < maxLevel; i++) {
|
||||
experience = experience + experienceLevelService.calculateExperienceForLevel(i - 1);
|
||||
experienceLevelService.createExperienceLevel(i, experience);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.experience.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:experience.properties")
|
||||
public class ExperienceProperties {
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package dev.sheldan.abstracto.experience.job;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceTrackerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@DisallowConcurrentExecution
|
||||
@Component
|
||||
@PersistJobDataAfterExecution
|
||||
public class ExperiencePersistingJob extends QuartzJobBean {
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||
HashMap<Long, List<AServer>> runtimeExperience = experienceTrackerService.getRuntimeExperience();
|
||||
log.info("Storing experience");
|
||||
Long pastMinute = (Instant.now().getEpochSecond() / 60) - 1;
|
||||
if(runtimeExperience.containsKey(pastMinute)) {
|
||||
experienceTrackerService.handleExperienceGain(runtimeExperience.get(pastMinute));
|
||||
runtimeExperience.remove(pastMinute);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package dev.sheldan.abstracto.experience.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
|
||||
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.service.ExperienceTrackerService;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
public class ExperienceTrackerListener implements MessageReceivedListener {
|
||||
|
||||
@Autowired
|
||||
private ExperienceTrackerService experienceTrackerService;
|
||||
|
||||
@Autowired
|
||||
private UserManagementService userManagementService;
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void execute(Message message) {
|
||||
AUserInAServer cause = userManagementService.loadUser(message.getMember());
|
||||
experienceTrackerService.addExperience(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeature() {
|
||||
return ExperienceFeatures.EXPERIENCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.experience.repository;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ExperienceLevelRepository extends JpaRepository<AExperienceLevel, Integer> {
|
||||
AExperienceLevel findTopByExperienceNeededGreaterThanOrderByExperienceNeededAsc(Long experience);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.experience.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceRole;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ExperienceRoleRepository extends JpaRepository<AExperienceRole, Long> {
|
||||
AExperienceRole findByRoleServerAndRole(AServer server, ARole role);
|
||||
List<AExperienceRole> findByLevelAndRoleServer(AExperienceLevel level, AServer server);
|
||||
List<AExperienceRole> findByRoleServer(AServer server);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.experience.repository;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserExperienceRepository extends JpaRepository<AUserExperience, Long> {
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceLevelManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExperienceLevelServiceBean implements ExperienceLevelService {
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelManagementService experienceLevelManagementService;
|
||||
|
||||
@Override
|
||||
public void createExperienceLevel(Integer level, Long experienceNeeded) {
|
||||
if(!experienceLevelManagementService.levelExists(level)) {
|
||||
experienceLevelManagementService.createExperienceLevel(level, experienceNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long calculateExperienceForLevel(Integer level) {
|
||||
return 5L * (level * level) + 50 * level + 100;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleManagementService experienceRoleManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelManagementService experienceLevelService;
|
||||
|
||||
@Override
|
||||
public void setRoleToLevel(ARole role, Integer level, AServer server) {
|
||||
AExperienceLevel experienceLevel = experienceLevelService.getLevel(level);
|
||||
experienceRoleManagementService.unSetLevelInServer(experienceLevel, server);
|
||||
experienceRoleManagementService.setLevelToRole(experienceLevel, role, server);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
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.RoleService;
|
||||
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.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ExperienceTrackerServiceBean implements ExperienceTrackerService {
|
||||
|
||||
private HashMap<Long, List<AServer>> runtimeExperience = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelService experienceLevelService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelManagementService experienceLevelManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleManagementService experienceRoleManagementService;
|
||||
|
||||
@Autowired
|
||||
private ConfigService configService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
@Override
|
||||
public void addExperience(AUserInAServer userInAServer) {
|
||||
Long second = Instant.now().getEpochSecond() / 60;
|
||||
if(runtimeExperience.containsKey(second)) {
|
||||
List<AServer> existing = runtimeExperience.get(second);
|
||||
existing.forEach(server -> {
|
||||
if(server.getUsers().stream().noneMatch(userInAServer1 -> userInAServer.getUserInServerId().equals(userInAServer1.getUserInServerId()))) {
|
||||
server.getUsers().add(userInAServer);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
AServer server = AServer
|
||||
.builder()
|
||||
.id(userInAServer.getServerReference().getId())
|
||||
.build();
|
||||
server.getUsers().add(userInAServer);
|
||||
runtimeExperience.put(second, Arrays.asList(server));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, List<AServer>> getRuntimeExperience() {
|
||||
return runtimeExperience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer calculateLevel(AUserExperience userInAServer, List<AExperienceLevel> levels) {
|
||||
AExperienceLevel lastLevel = levels.get(0);
|
||||
for (AExperienceLevel level : levels) {
|
||||
if(level.getExperienceNeeded() >= userInAServer.getExperience()) {
|
||||
return lastLevel.getLevel();
|
||||
} else {
|
||||
lastLevel = level;
|
||||
}
|
||||
}
|
||||
return lastLevel.getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceRole calculateRole(AUserExperience userInAServer, List<AExperienceRole> roles) {
|
||||
if(roles.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
AExperienceRole lastRole = null;
|
||||
for (AExperienceRole experienceRole : roles) {
|
||||
if(userInAServer.getCurrentLevel().getLevel() >= experienceRole.getLevel().getLevel()) {
|
||||
lastRole = experienceRole;
|
||||
} else {
|
||||
return experienceRole;
|
||||
}
|
||||
}
|
||||
return lastRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseExpForUser(AUserExperience userInAServer, Long experience, List<AExperienceLevel> levels) {
|
||||
userInAServer.setExperience(userInAServer.getExperience() + experience);
|
||||
Integer correctLevel = calculateLevel(userInAServer, levels);
|
||||
Integer currentLevel = userInAServer.getCurrentLevel() != null ? userInAServer.getCurrentLevel().getLevel() : 0;
|
||||
if(!correctLevel.equals(currentLevel)) {
|
||||
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());
|
||||
int minExp = configService.getDoubleValue("minExp", serverExp.getId()).intValue();
|
||||
int maxExp = configService.getDoubleValue("maxExp", serverExp.getId()).intValue();
|
||||
Integer multiplier = configService.getDoubleValue("multiplier", serverExp.getId()).intValue();
|
||||
PrimitiveIterator.OfInt iterator = new Random().ints(serverExp.getUsers().size(), minExp, maxExp + 1).iterator();
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRoleForServer(serverExp);
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
serverExp.getUsers().forEach(userInAServer -> {
|
||||
Integer gainedExperience = iterator.next();
|
||||
gainedExperience *= multiplier;
|
||||
log.info("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
|
||||
AUserExperience userExperience = userExperienceManagementService.findUserInServer(userInAServer);
|
||||
increaseExpForUser(userExperience, gainedExperience.longValue(), levels);
|
||||
handleExperienceRoleForUser(userExperience, roles);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleExperienceRoleForUser(AUserExperience userExperience, List<AExperienceRole> roles) {
|
||||
AExperienceRole role = calculateRole(userExperience, roles);
|
||||
if(role == null) {
|
||||
return;
|
||||
}
|
||||
boolean currentlyHasNoExperienceRole = userExperience.getCurrentExperienceRole() == null;
|
||||
if(currentlyHasNoExperienceRole || !role.getRole().getId().equals(userExperience.getCurrentExperienceRole().getId())) {
|
||||
log.info("User {} gets a new role {}", userExperience.getUser().getUserReference().getId(), role.getRole().getId());
|
||||
if(!currentlyHasNoExperienceRole) {
|
||||
roleService.removeRoleFromUser(userExperience.getUser(), userExperience.getCurrentExperienceRole().getRole());
|
||||
}
|
||||
userExperience.setCurrentExperienceRole(role);
|
||||
roleService.addRoleToUser(userExperience.getUser(), userExperience.getCurrentExperienceRole().getRole());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
import dev.sheldan.abstracto.experience.repository.ExperienceLevelRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ExperienceLevelManagementServiceBean implements ExperienceLevelManagementService {
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelRepository experienceLevelRepository;
|
||||
|
||||
@Override
|
||||
public AExperienceLevel createExperienceLevel(Integer level, Long neededExperience) {
|
||||
AExperienceLevel experienceLevel = AExperienceLevel
|
||||
.builder()
|
||||
.experienceNeeded(neededExperience)
|
||||
.level(level)
|
||||
.build();
|
||||
experienceLevelRepository.save(experienceLevel);
|
||||
return experienceLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean levelExists(Integer level) {
|
||||
return experienceLevelRepository.existsById(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceLevel getLevel(Integer level) {
|
||||
return experienceLevelRepository.getOne(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AExperienceLevel getLevelClosestTo(Long experience) {
|
||||
return experienceLevelRepository.findTopByExperienceNeededGreaterThanOrderByExperienceNeededAsc(experience);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceLevel> getLevelConfig() {
|
||||
return experienceLevelRepository.findAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
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.repository.ExperienceRoleRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ExperienceRoleManagementServiceBean implements ExperienceRoleManagementService {
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleRepository experienceRoleRepository;
|
||||
|
||||
@Override
|
||||
public void unSetLevelInServer(AExperienceLevel level, AServer server) {
|
||||
List<AExperienceRole> existingExperienceRoles = experienceRoleRepository.findByLevelAndRoleServer(level, server);
|
||||
existingExperienceRoles.forEach(existingRole -> {
|
||||
experienceRoleRepository.delete(existingRole);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AExperienceRole> getExperienceRoleForServer(AServer server) {
|
||||
return experienceRoleRepository.findByRoleServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLevelToRole(AExperienceLevel level, ARole role, AServer server) {
|
||||
AExperienceRole byRoleServerAndRole = experienceRoleRepository.findByRoleServerAndRole(server, role);
|
||||
if(byRoleServerAndRole != null) {
|
||||
byRoleServerAndRole.setLevel(level);
|
||||
} else {
|
||||
byRoleServerAndRole = AExperienceRole
|
||||
.builder()
|
||||
.level(level)
|
||||
.roleServer(server)
|
||||
.role(role)
|
||||
.build();
|
||||
}
|
||||
experienceRoleRepository.save(byRoleServerAndRole);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
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.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@Component
|
||||
public class UserExperienceManagementServiceBean implements UserExperienceManagementService {
|
||||
|
||||
@Autowired
|
||||
private UserExperienceRepository repository;
|
||||
|
||||
@Autowired
|
||||
private ExperienceLevelManagementService experienceLevelManagementService;
|
||||
|
||||
@Override
|
||||
public void setExperienceTo(AUserExperience aUserInAServer, Long experience) {
|
||||
aUserInAServer.setExperience(experience);
|
||||
repository.save(aUserInAServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserExperience findUserInServer(AUserInAServer aUserInAServer) {
|
||||
Optional<AUserExperience> byId = repository.findById(aUserInAServer.getUserInServerId());
|
||||
return byId.orElseGet(() -> createUserInServer(aUserInAServer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserExperience createUserInServer(AUserInAServer aUserInAServer) {
|
||||
AExperienceLevel startingLevel = experienceLevelManagementService.getLevel(0);
|
||||
AUserExperience userExperience = AUserExperience
|
||||
.builder()
|
||||
.experience(0L)
|
||||
.user(aUserInAServer)
|
||||
.id(aUserInAServer.getUserInServerId())
|
||||
.currentLevel(startingLevel)
|
||||
.build();
|
||||
repository.save(userExperience);
|
||||
return userExperience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUser(AUserExperience userExperience) {
|
||||
repository.save(userExperience);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
abstracto.scheduling.jobs.experienceJob.name=experienceJob
|
||||
abstracto.scheduling.jobs.experienceJob.group=experience
|
||||
abstracto.scheduling.jobs.experienceJob.clazz=dev.sheldan.abstracto.experience.job.ExperiencePersistingJob
|
||||
abstracto.scheduling.jobs.experienceJob.standAlone=true
|
||||
abstracto.scheduling.jobs.experienceJob.active=true
|
||||
abstracto.scheduling.jobs.experienceJob.cronExpression=30 * * * * ?
|
||||
|
||||
|
||||
abstracto.features.experience=true
|
||||
|
||||
abstracto.experience.minExp=10
|
||||
abstracto.experience.maxExp=25
|
||||
abstracto.experience.multiplier=1
|
||||
abstracto.experience.maxLvl=200
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>experience-tracking-int</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.templating</groupId>
|
||||
<artifactId>templating-interface</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.scheduling</groupId>
|
||||
<artifactId>scheduling-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.experience.models.database;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "experience_level")
|
||||
@Getter
|
||||
@Setter
|
||||
public class AExperienceLevel {
|
||||
@Id
|
||||
private Integer level;
|
||||
private Long experienceNeeded;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package dev.sheldan.abstracto.experience.models.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "experience_role")
|
||||
@Getter
|
||||
@Setter
|
||||
public class AExperienceRole {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "level_id")
|
||||
private AExperienceLevel level;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@Getter
|
||||
@Setter
|
||||
@JoinColumn(name = "server_id")
|
||||
private AServer roleServer;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "role_id")
|
||||
private ARole role;
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = CascadeType.ALL,
|
||||
orphanRemoval = true)
|
||||
@Builder.Default
|
||||
@JoinColumn(name = "experience_role_id")
|
||||
private List<AUserExperience> users = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "user_experience")
|
||||
@Getter
|
||||
@Setter
|
||||
public class AUserExperience {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@PrimaryKeyJoinColumn
|
||||
private AUserInAServer user;
|
||||
|
||||
private Long experience;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "level_id")
|
||||
private AExperienceLevel currentLevel;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "experience_role_id")
|
||||
private AExperienceRole currentExperienceRole;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
public interface ExperienceLevelService {
|
||||
void createExperienceLevel(Integer level, Long experienceNeeded);
|
||||
Long calculateExperienceForLevel(Integer level);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExperienceLevelManagementService {
|
||||
AExperienceLevel createExperienceLevel(Integer level, Long neededExperience);
|
||||
boolean levelExists(Integer level);
|
||||
AExperienceLevel getLevel(Integer level);
|
||||
AExperienceLevel getLevelClosestTo(Long experience);
|
||||
List<AExperienceLevel> getLevelConfig();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
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 java.util.List;
|
||||
|
||||
public interface ExperienceRoleManagementService {
|
||||
void setLevelToRole(AExperienceLevel level, ARole role, AServer server);
|
||||
void unSetLevelInServer(AExperienceLevel level, AServer server);
|
||||
List<AExperienceRole> getExperienceRoleForServer(AServer server);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.experience.service.management;
|
||||
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
|
||||
|
||||
public interface UserExperienceManagementService {
|
||||
void setExperienceTo(AUserExperience aUserInAServer, Long experience);
|
||||
AUserExperience findUserInServer(AUserInAServer aUserInAServer);
|
||||
AUserExperience createUserInServer(AUserInAServer aUserInAServer);
|
||||
void saveUser(AUserExperience userExperience);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>experience-tracking-int</module>
|
||||
<module>experience-tracking-impl</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>core-interface</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Reference in New Issue
Block a user