Compare commits

...
31 Commits
Author SHA1 Message Date
Sheldan 6c6cd130aa [AB-xxx] changing types of ids to be string instead for javascript purposes 2024-04-05 15:06:10 +02:00
release-bot 65a1d44069 Commit from GitHub Actions (Publishes a new version of abstracto) 2024-04-05 12:43:58 +00:00
release-bot 11312a5e27 [maven-release-plugin] prepare for next development iteration 2024-04-05 12:29:23 +00:00
release-bot 6b13958ac0 [maven-release-plugin] prepare release v1.5.34 2024-04-05 12:29:20 +00:00
Sheldan 3142daafd3 [AB-xxx] renaming leaderboard url property 2024-04-05 01:58:43 +02:00
Sheldan 4bef78f847 [AB-xxx] adding link to the leaderboard to the leaderboard command response 2024-04-05 01:40:06 +02:00
Sheldan 82be86e086 [AB-xxx] adding locking mechanism for role assignments to work around discord lack of role update locking 2024-04-04 22:54:18 +02:00
Sheldan bff505ef25 [AB-xxx] fixing not using the ban reason for moderation actions 2024-03-27 23:17:06 +01:00
release-bot 533f5671c2 [maven-release-plugin] prepare for next development iteration 2024-03-27 21:26:56 +00:00
release-bot 8c7547b485 [maven-release-plugin] prepare release v1.5.33 2024-03-27 21:26:54 +00:00
Sheldan 741c194bb8 [AB-xxx] changing styling for smaller screens for member display to truncate the name
prepare for release
2024-03-27 22:24:38 +01:00
release-bot d2bdfd8dac [maven-release-plugin] prepare for next development iteration 2024-03-26 22:54:50 +00:00
release-bot 36c67fbe20 [maven-release-plugin] prepare release v1.5.32 2024-03-26 22:54:47 +00:00
Sheldan 8fd1aede2a [AB-xxx] changing style of leaderboard table
preparing for release
2024-03-26 23:48:22 +01:00
release-bot 287ae1f0b1 [maven-release-plugin] prepare for next development iteration 2024-03-26 21:40:02 +00:00
release-bot 903361cb58 [maven-release-plugin] prepare release v1.5.31 2024-03-26 21:39:59 +00:00
Sheldan c8cf412a4a [AB-xxx] changing style of leaderboard table
preparing for release
2024-03-26 22:37:47 +01:00
release-bot affc249012 [maven-release-plugin] prepare for next development iteration 2024-03-26 21:17:03 +00:00
release-bot 653671ea79 [maven-release-plugin] prepare release v1.5.30 2024-03-26 21:17:00 +00:00
Sheldan 7185908682 [AB-xxx] prepare for release 2024-03-26 22:13:42 +01:00
Sheldan 675da8d5d8 [AB-xxx] adding rank to leaderboard page
changing design of leaderboard page
fixing role not having an id
2024-03-26 22:13:18 +01:00
release-bot e91becee0d [maven-release-plugin] prepare for next development iteration 2024-03-26 01:10:22 +00:00
release-bot 18732efe75 [maven-release-plugin] prepare release v1.5.29 2024-03-26 01:10:20 +00:00
Sheldan 63897fd914 [AB-xxx] prepare for release 2024-03-26 02:08:06 +01:00
Sheldan 9b865af43b [AB-xxx] fixing not serving static files 2024-03-26 02:07:25 +01:00
release-bot b78275734c [maven-release-plugin] prepare for next development iteration 2024-03-26 00:36:30 +00:00
release-bot 00a6b0d1f8 [maven-release-plugin] prepare release v1.5.28 2024-03-26 00:36:28 +00:00
Sheldan 13fe6f5e51 [AB-xxx] prepare for release 2024-03-26 01:31:53 +01:00
Sheldan bc0c3a18d7 [AB-xxx] initial experience leaderboard version 2024-03-26 01:28:56 +01:00
release-bot 8f9b7eba16 Commit from GitHub Actions (Publishes a new version of abstracto) 2024-03-17 12:10:52 +00:00
release-bot 48eacb2e1c [maven-release-plugin] prepare for next development iteration 2024-03-17 12:02:17 +00:00
138 changed files with 17771 additions and 100 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
VERSION=1.5.26
VERSION=1.5.34
+10
View File
@@ -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
View File
@@ -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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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(String.valueOf(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(String.valueOf(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 String 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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-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</version>
<version>1.5.35-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto</groupId>
<artifactId>abstracto-application</artifactId>
<version>1.5.27</version>
<version>1.5.35-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core</artifactId>
<version>1.5.27</version>
<version>1.5.35-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.getId())
.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;
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core</artifactId>
<version>1.5.27</version>
<version>1.5.35-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 String 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 String 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.getId());
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(String.valueOf(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 String id;
public static UserDisplay fromMember(Member member) {
return builder()
.avatarUrl(member.getEffectiveAvatarUrl())
.name(member.getEffectiveName())
.id(member.getId())
.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