mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-04 08:42:45 +00:00
Compare commits
28 Commits
2024031712
...
2024040512
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3142daafd3 | ||
|
|
4bef78f847 | ||
|
|
82be86e086 | ||
|
|
bff505ef25 | ||
|
|
533f5671c2 | ||
|
|
8c7547b485 | ||
|
|
741c194bb8 | ||
|
|
d2bdfd8dac | ||
|
|
36c67fbe20 | ||
|
|
8fd1aede2a | ||
|
|
287ae1f0b1 | ||
|
|
903361cb58 | ||
|
|
c8cf412a4a | ||
|
|
affc249012 | ||
|
|
653671ea79 | ||
|
|
7185908682 | ||
|
|
675da8d5d8 | ||
|
|
e91becee0d | ||
|
|
18732efe75 | ||
|
|
63897fd914 | ||
|
|
9b865af43b | ||
|
|
b78275734c | ||
|
|
00a6b0d1f8 | ||
|
|
13fe6f5e51 | ||
|
|
bc0c3a18d7 | ||
|
|
8f9b7eba16 | ||
|
|
48eacb2e1c | ||
|
|
2168814814 |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
||||
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
||||
VERSION=1.5.26
|
||||
VERSION=1.5.33
|
||||
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -25,8 +25,18 @@ jobs:
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 17
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '21.x'
|
||||
- name: Build with Maven
|
||||
run: mvn -B install --file abstracto-application/pom.xml
|
||||
- name: Install node dependencies and build
|
||||
working-directory: ./ui/experience-tracking
|
||||
run: npm ci
|
||||
- name: Build ui application
|
||||
working-directory: ./ui/experience-tracking
|
||||
run: npm run build
|
||||
- uses: actions/setup-ruby@v1
|
||||
- name: Send Webhook Notification
|
||||
if: always()
|
||||
|
||||
12
.github/workflows/release_manual.yml
vendored
12
.github/workflows/release_manual.yml
vendored
@@ -15,6 +15,10 @@ jobs:
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 17
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '21.x'
|
||||
- name: Load current version
|
||||
id: version
|
||||
working-directory: ./abstracto-application
|
||||
@@ -37,6 +41,14 @@ jobs:
|
||||
release-branch-name: master
|
||||
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
|
||||
access-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Install node dependencies and build
|
||||
working-directory: ./ui/experience-tracking
|
||||
run: npm ci
|
||||
- name: Build ui application
|
||||
working-directory: ./ui/experience-tracking
|
||||
run: npm run build
|
||||
- name: Copy built UI
|
||||
run: cp -R ui/experience-tracking/build/* python/components/experience-tracking/resources/templates/experience/leaderboards/
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -38,6 +38,16 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.sheldan.abstracto.experience.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.frontend.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.service.GuildService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.experience.model.api.ExperienceConfig;
|
||||
import dev.sheldan.abstracto.experience.model.api.ExperienceRoleDisplay;
|
||||
import dev.sheldan.abstracto.experience.model.template.LevelRole;
|
||||
import dev.sheldan.abstracto.experience.service.ExperienceRoleService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/experience/v1/")
|
||||
public class ExperienceConfigController {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ExperienceRoleService experienceRoleService;
|
||||
|
||||
@Autowired
|
||||
private GuildService guildService;
|
||||
|
||||
@GetMapping(value = "/leaderboards/{serverId}/config", produces = "application/json")
|
||||
public ExperienceConfig getLeaderboard(@PathVariable("serverId") Long serverId) {
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
List<LevelRole> levelRoles = experienceRoleService.loadLevelRoleConfigForServer(server);
|
||||
levelRoles = levelRoles.stream().sorted(Comparator.comparingInt(LevelRole::getLevel).reversed()).toList();
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
List<ExperienceRoleDisplay> roles = levelRoles
|
||||
.stream()
|
||||
.map(levelRole -> convertRole(levelRole, guild))
|
||||
.toList();
|
||||
return ExperienceConfig
|
||||
.builder()
|
||||
.roles(roles)
|
||||
.build();
|
||||
}
|
||||
|
||||
private ExperienceRoleDisplay convertRole(LevelRole levelRole, Guild guild) {
|
||||
Role guildRole = guild.getRoleById(levelRole.getRoleId());
|
||||
RoleDisplay roleDisplay;
|
||||
if(guildRole != null) {
|
||||
roleDisplay = RoleDisplay.fromRole(guildRole);
|
||||
} else {
|
||||
roleDisplay = RoleDisplay
|
||||
.builder()
|
||||
.id(levelRole.getRoleId())
|
||||
.build();
|
||||
}
|
||||
return ExperienceRoleDisplay
|
||||
.builder()
|
||||
.level(levelRole.getLevel())
|
||||
.role(roleDisplay)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package dev.sheldan.abstracto.experience.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.frontend.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.models.frontend.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.GuildService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.experience.model.api.UserExperienceDisplay;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.entities.UserSnowflake;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/experience/v1")
|
||||
public class LeaderboardController {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Autowired
|
||||
private GuildService guildService;
|
||||
|
||||
@GetMapping(value = "/leaderboards/{serverId}", produces = "application/json")
|
||||
public Page<UserExperienceDisplay> getLeaderboard(@PathVariable("serverId") Long serverId,
|
||||
@PageableDefault(value = 25, page = 0)
|
||||
@SortDefault(sort = "experience", direction = Sort.Direction.DESC)
|
||||
Pageable pageable) {
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
Page<AUserExperience> allElements = userExperienceManagementService.loadAllUsersPaginated(server, pageable);
|
||||
return allElements
|
||||
.map(userExperience -> convertFromUser(guild, userExperience, pageable, allElements));
|
||||
}
|
||||
|
||||
private UserExperienceDisplay convertFromUser(Guild guild, AUserExperience aUserExperience, Pageable pageable, Page<AUserExperience> page) {
|
||||
Long userId = aUserExperience.getUser().getUserReference().getId();
|
||||
Member member = guild.getMember(UserSnowflake.fromId(userId));
|
||||
AExperienceRole experienceRole = aUserExperience.getCurrentExperienceRole();
|
||||
UserDisplay userDisplay = null;
|
||||
RoleDisplay roleDisplay = null;
|
||||
if(experienceRole != null) {
|
||||
Role role = guild.getRoleById(experienceRole.getRole().getId());
|
||||
if(role != null) {
|
||||
roleDisplay = RoleDisplay.fromRole(role);
|
||||
} else {
|
||||
roleDisplay = RoleDisplay.fromARole(experienceRole.getRole());
|
||||
}
|
||||
}
|
||||
if(member != null) {
|
||||
userDisplay = UserDisplay.fromMember(member);
|
||||
}
|
||||
return UserExperienceDisplay
|
||||
.builder()
|
||||
.id(userId)
|
||||
.messages(aUserExperience.getMessageCount())
|
||||
.level(aUserExperience.getLevelOrDefault())
|
||||
.rank((int) pageable.getOffset() + page.getContent().indexOf(aUserExperience) + 1)
|
||||
.experience(aUserExperience.getExperience())
|
||||
.role(roleDisplay)
|
||||
.member(userDisplay)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,9 @@ import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -70,6 +72,9 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Value("${abstracto.experience.leaderboard.externalUrl}")
|
||||
private String leaderboardExternalURL;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -91,11 +96,18 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
|
||||
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(aUserInAServer);
|
||||
CompletableFuture<List<LeaderBoardEntryModel>> userRankFuture = converter.fromLeaderBoardEntry(Arrays.asList(userRank));
|
||||
futures.add(userRankFuture);
|
||||
String leaderboardUrl;
|
||||
if(!StringUtils.isBlank(leaderboardExternalURL)) {
|
||||
leaderboardUrl = String.format("%s/experience/leaderboards/%s", leaderboardExternalURL, actorUser.getGuild().getIdLong());
|
||||
} else {
|
||||
leaderboardUrl = null;
|
||||
}
|
||||
return FutureUtils.toSingleFuture(futures).thenCompose(aVoid -> {
|
||||
List<LeaderBoardEntryModel> finalModels = completableFutures.join();
|
||||
LeaderBoardModel leaderBoardModel = LeaderBoardModel
|
||||
.builder()
|
||||
.userExperiences(finalModels)
|
||||
.leaderboardUrl(leaderboardUrl)
|
||||
.userExecuting(userRankFuture.join().get(0))
|
||||
.build();
|
||||
return CompletableFuture.completedFuture(templateService.renderEmbedTemplate(LEADER_BOARD_POST_EMBED_TEMPLATE, leaderBoardModel, actorUser.getGuild().getIdLong()));
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.experience.model.api;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ExperienceConfig {
|
||||
private List<ExperienceRoleDisplay> roles;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.experience.model.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.frontend.RoleDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ExperienceRoleDisplay {
|
||||
private RoleDisplay role;
|
||||
private Integer level;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.sheldan.abstracto.experience.model.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.frontend.RoleDisplay;
|
||||
import dev.sheldan.abstracto.core.models.frontend.UserDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class UserExperienceDisplay {
|
||||
private UserDisplay member;
|
||||
private Long id;
|
||||
private Integer rank;
|
||||
private Integer level;
|
||||
private Long experience;
|
||||
private Long messages;
|
||||
private RoleDisplay role;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.experience.repository;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.model.database.LeaderBoardEntryResult;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
@@ -24,6 +25,7 @@ public interface UserExperienceRepository extends JpaRepository<AUserExperience
|
||||
* @return A complete list of {@link AUserExperience} of the given {@link AServer server}
|
||||
*/
|
||||
List<AUserExperience> findByUser_ServerReference(AServer server);
|
||||
Page<AUserExperience> findAllByServer(AServer server, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Retrieves the {@link AUserExperience userExperience} ordered by experience, and applies the {@link Pageable pageable} to only filter out certain pages.
|
||||
|
||||
@@ -166,7 +166,10 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
List<LevelRole> levelRoles = new ArrayList<>();
|
||||
roles.forEach(aExperienceRole -> {
|
||||
Role role = roleService.getRoleFromGuild(aExperienceRole.getRole());
|
||||
Role role = null;
|
||||
if(!aExperienceRole.getRole().getDeleted()) {
|
||||
role = roleService.getRoleFromGuild(aExperienceRole.getRole());
|
||||
}
|
||||
LevelRole levelRole = LevelRole
|
||||
.builder()
|
||||
.role(role)
|
||||
|
||||
@@ -11,7 +11,9 @@ import dev.sheldan.abstracto.experience.model.database.LeaderBoardEntryResult;
|
||||
import dev.sheldan.abstracto.experience.repository.UserExperienceRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@@ -70,6 +72,11 @@ public class UserExperienceManagementServiceBean implements UserExperienceManage
|
||||
return repository.findByUser_ServerReference(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AUserExperience> loadAllUsersPaginated(AServer server, Pageable pageable) {
|
||||
return repository.findAllByServer(server, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AUserExperience> findLeaderBoardUsersPaginated(AServer aServer, Integer page, Integer size) {
|
||||
return repository.findTop10ByUser_ServerReferenceOrderByExperienceDesc(aServer, PageRequest.of(page, size));
|
||||
|
||||
@@ -17,4 +17,6 @@ abstracto.featureModes.levelUpNotification.enabled=false
|
||||
|
||||
abstracto.featureModes.levelAction.featureName=experience
|
||||
abstracto.featureModes.levelAction.mode=levelAction
|
||||
abstracto.featureModes.levelAction.enabled=false
|
||||
abstracto.featureModes.levelAction.enabled=false
|
||||
|
||||
abstracto.experience.leaderboard.externalUrl=${FRONTEND_BASE:}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -24,4 +24,5 @@ public class LeaderBoardModel extends SlimUserInitiatedServerContext {
|
||||
* The {@link LeaderBoardEntryModel} containing the leaderboard information executing the command.
|
||||
*/
|
||||
private LeaderBoardEntryModel userExecuting;
|
||||
private String leaderboardUrl;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.experience.model.database.AExperienceRole;
|
||||
import dev.sheldan.abstracto.experience.model.database.AUserExperience;
|
||||
import dev.sheldan.abstracto.experience.model.database.LeaderBoardEntryResult;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -50,6 +52,7 @@ public interface UserExperienceManagementService {
|
||||
* @return A list of {@link AUserExperience} objects associated with the given {@link AServer}
|
||||
*/
|
||||
List<AUserExperience> loadAllUsers(AServer server);
|
||||
Page<AUserExperience> loadAllUsersPaginated(AServer server, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Retrieves a list of {@link AUserExperience} ordered by {@link AUserExperience} experience and only returns the positions between {@code start} and @{code end}.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>image-generation</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-int</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>invite-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation-int</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>link-embed</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>logging</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class BanModerationActionModalListener implements ModalInteractionListene
|
||||
.getEvent()
|
||||
.getValues()
|
||||
.stream()
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getDurationInputId()))
|
||||
.filter(modalMapping -> modalMapping.getId().equals(payload.getReasonInputId()))
|
||||
.map(ModalMapping::getAsString)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>moderation</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>modmail</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>profanity-filter</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>remind</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>repost-detection</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>starboard</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>statistic</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>sticky-roles</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sticky-roles-impl</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>sticky-roles</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sticky-roles-int</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>suggestion</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>twitch</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>twitch</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>utility</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>voice-channel-context</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>voice-channel-context</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>webservices</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>webservices</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto</groupId>
|
||||
<artifactId>abstracto-application</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.core.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class ExceptionHandlerConfig {
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
@ExceptionHandler(GuildNotFoundException.class)
|
||||
protected ResponseEntity<String> handleResourceNotFound(GuildNotFoundException ex){
|
||||
log.warn("Server not found.", ex);
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.NOT_FOUND)
|
||||
.body("Server not found");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package dev.sheldan.abstracto.core.api;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.api.GuildDisplay;
|
||||
import dev.sheldan.abstracto.core.service.GuildService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/servers/v1/")
|
||||
public class ServerController {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private GuildService guildService;
|
||||
|
||||
@GetMapping(value = "/{serverId}/info", produces = "application/json")
|
||||
public GuildDisplay getLeaderboard(@PathVariable("serverId") Long serverId) {
|
||||
serverManagementService.loadServer(serverId); // only used for verification if it exists in the db
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
return GuildDisplay
|
||||
.builder()
|
||||
.name(guild.getName())
|
||||
.id(guild.getIdLong())
|
||||
.bannerUrl(guild.getBannerUrl())
|
||||
.iconUrl(guild.getIconUrl())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,12 @@ import dev.sheldan.abstracto.core.exception.RoleNotFoundInGuildException;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.LockByKeyService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -46,6 +48,9 @@ public class RoleServiceBean implements RoleService {
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private LockByKeyService<ServerUser> roleLockService;
|
||||
|
||||
public static final CounterMetric ROLE_ASSIGNED_METRIC = CounterMetric
|
||||
.builder()
|
||||
.name(DISCORD_API_INTERACTION_METRIC)
|
||||
@@ -113,12 +118,31 @@ public class RoleServiceBean implements RoleService {
|
||||
.map(guild::getRoleById)
|
||||
.toList();
|
||||
Member member = memberService.getMemberInServer(aUserInAServer);
|
||||
return guild.modifyMemberRoles(member, rolesObjToAdd, rolesObjToRemove).submit();
|
||||
return updateRolesObj(member, rolesObjToRemove, rolesObjToAdd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updateRolesObj(Member member, List<Role> rolesToRemove, List<Role> rolesToAdd) {
|
||||
return member.getGuild().modifyMemberRoles(member, rolesToAdd, rolesToRemove).submit();
|
||||
ServerUser serverUser = ServerUser.fromId(member.getGuild().getIdLong(), member.getIdLong()); // only use ids, so its completely comparable with the other server users
|
||||
try {
|
||||
roleLockService.lock(serverUser);
|
||||
return member.getGuild().modifyMemberRoles(member, rolesToAdd, rolesToRemove).submit()
|
||||
.whenComplete((unused, throwable) -> roleLockService.unlock(serverUser));
|
||||
/*
|
||||
the intended reason why we only have it in a catch block:
|
||||
the "finally" block runs before the whenComplete block, which would lead
|
||||
to be possibility of another request being done immediately, and also doing it twice
|
||||
We only unlock synchronously in case of an exception, because then something _before_ the future
|
||||
actually failed. The future (whenComplete) is _never_ evaluated in such a case
|
||||
this is also the case in addRoleToMemberAsync and removeRoleFromUserAsync
|
||||
*/
|
||||
} catch (InterruptedException interruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
return CompletableFuture.failedFuture(interruptedException);
|
||||
} catch (Exception e) {
|
||||
roleLockService.unlock(serverUser);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,7 +188,7 @@ public class RoleServiceBean implements RoleService {
|
||||
if(role == null) {
|
||||
throw new RoleNotFoundInGuildException(roleId, member.getGuild().getIdLong());
|
||||
}
|
||||
return member.getGuild().removeRoleFromMember(member, role).submit();
|
||||
return removeRoleFromUserAsync(member.getGuild(), member.getIdLong(), role);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> addRoleToUserAsync(Guild guild, Long userId, ARole role) {
|
||||
@@ -180,13 +204,35 @@ public class RoleServiceBean implements RoleService {
|
||||
@Override
|
||||
public CompletableFuture<Void> addRoleToMemberAsync(Guild guild, Long userId, Role roleById) {
|
||||
metricService.incrementCounter(ROLE_ASSIGNED_METRIC);
|
||||
return guild.addRoleToMember(UserSnowflake.fromId(userId), roleById).submit();
|
||||
ServerUser serverUser = ServerUser.fromId(guild.getIdLong(), userId);
|
||||
try {
|
||||
roleLockService.lock(serverUser);
|
||||
return guild.addRoleToMember(UserSnowflake.fromId(userId), roleById).submit()
|
||||
.whenComplete((unused, ex) -> roleLockService.unlock(serverUser));
|
||||
} catch (InterruptedException interruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
return CompletableFuture.failedFuture(interruptedException);
|
||||
} catch (Exception e){ // see updateRolesObj for why
|
||||
roleLockService.unlock(serverUser);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeRoleFromUserAsync(Guild guild, Long userId, Role roleById) {
|
||||
metricService.incrementCounter(ROLE_REMOVED_METRIC);
|
||||
return guild.removeRoleFromMember(UserSnowflake.fromId(userId), roleById).submit();
|
||||
ServerUser serverUser = ServerUser.fromId(guild.getIdLong(), userId);
|
||||
try {
|
||||
roleLockService.lock(serverUser);
|
||||
return guild.removeRoleFromMember(UserSnowflake.fromId(userId), roleById).submit()
|
||||
.whenComplete((unused, ex) -> roleLockService.unlock(serverUser));
|
||||
} catch (InterruptedException interruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
return CompletableFuture.failedFuture(interruptedException);
|
||||
} catch (Exception e) { // see updateRolesObj for why
|
||||
roleLockService.unlock(serverUser);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>1.5.27-SNAPSHOT</version>
|
||||
<version>1.5.34-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.models;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.*;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -12,10 +9,12 @@ import java.io.Serializable;
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class ServerUser implements Serializable {
|
||||
private Long serverId;
|
||||
private Long userId;
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Boolean isBot;
|
||||
|
||||
public static ServerUser fromAUserInAServer(AUserInAServer aUserInAServer) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.core.models.api;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class GuildDisplay {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String iconUrl;
|
||||
private String bannerUrl;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.sheldan.abstracto.core.models.frontend;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class RoleDisplay {
|
||||
private Long id;
|
||||
private String name;
|
||||
private Integer r;
|
||||
private Integer g;
|
||||
private Integer b;
|
||||
|
||||
public static RoleDisplay fromRole(Role role) {
|
||||
RoleDisplayBuilder builder = builder()
|
||||
.name(role.getName())
|
||||
.id(role.getIdLong());
|
||||
Color roleColor = role.getColor();
|
||||
if(roleColor != null) {
|
||||
builder.r(roleColor.getRed()).
|
||||
b(roleColor.getBlue())
|
||||
.g(roleColor.getGreen());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
public static RoleDisplay fromARole(ARole role) {
|
||||
return builder()
|
||||
.id(role.getId())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.models.frontend;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class UserDisplay {
|
||||
private String avatarUrl;
|
||||
private String name;
|
||||
private Long id;
|
||||
|
||||
public static UserDisplay fromMember(Member member) {
|
||||
return builder()
|
||||
.avatarUrl(member.getEffectiveAvatarUrl())
|
||||
.name(member.getEffectiveName())
|
||||
.id(member.getIdLong())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
// https://www.baeldung.com/java-acquire-lock-by-key
|
||||
public class LockByKeyService<Key> {
|
||||
private static class LockWrapper {
|
||||
private final Semaphore lock = new Semaphore(1);
|
||||
private final AtomicInteger numberOfThreadsInQueue = new AtomicInteger(1);
|
||||
|
||||
private LockWrapper addThreadInQueue() {
|
||||
numberOfThreadsInQueue.incrementAndGet();
|
||||
return this;
|
||||
}
|
||||
|
||||
private int removeThreadFromQueue() {
|
||||
return numberOfThreadsInQueue.decrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
private final ConcurrentHashMap<Key, LockWrapper> locks = new ConcurrentHashMap<>();
|
||||
|
||||
public void lock(Key key) throws InterruptedException {
|
||||
LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
|
||||
lockWrapper.lock.acquire();
|
||||
}
|
||||
|
||||
public void unlock(Key key) {
|
||||
LockWrapper lockWrapper = locks.get(key);
|
||||
lockWrapper.lock.release();
|
||||
if (lockWrapper.removeThreadFromQueue() == 0) {
|
||||
locks.remove(key, lockWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user