[AB-302] refactoring assignable roles to use buttons instead of reactions

moved button related services to component service instead of message service
adding component type to component payload
renamed async role service methods
ignoring bot reactions in starboard
fixing rank not showing correct experience to next level for other members
This commit is contained in:
Sheldan
2021-07-09 02:00:33 +02:00
parent c08134a150
commit 7e7591a4b3
117 changed files with 1886 additions and 2470 deletions

View File

@@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to activate an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
@@ -30,23 +31,24 @@ public class ActivateAssignableRolePlace extends AbstractConditionableCommand {
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
service.activateAssignableRolePlace(server, name);
return CommandResult.fromSuccess();
return service.activateAssignableRolePlace(server, name)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName);
Parameter placeName = Parameter.builder().name("name").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(placeName);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("activateAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -1,7 +1,8 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -9,52 +10,44 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/**
* Command used to set the position of one individual {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole assignableRole}
* within an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class SetAssignableRolePosition extends AbstractConditionableCommand {
public class AddAssignableRoleCondition extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
private AssignableRoleConditionService assignableRoleConditionService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
FullEmote emote = (FullEmote) parameters.get(1);
Integer newPosition = (Integer) parameters.get(2);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
service.setEmoteToPosition(server, name, emote, newPosition);
Role role = (Role) parameters.get(1);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2);
String parameterValue = (String) parameters.get(3);
assignableRoleConditionService.createAssignableRoleCondition(name, role, configKey, parameterValue);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter emote = Parameter.builder().name("emote").type(FullEmote.class).templated(true).build();
Parameter newPosition = Parameter.builder().name("newPosition").type(Integer.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName, emote, newPosition);
Parameter placeName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter role = Parameter.builder().name("role").type(Role.class).templated(true).build();
Parameter conditionKey = Parameter.builder().name("conditionKey").type(AssignableRoleConditionType.class).templated(true).build();
Parameter conditionValue = Parameter.builder().name("conditionParameter").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey, conditionValue);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("setAssignableRolePosition")
.name("addAssignableRoleCondition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();

View File

@@ -1,7 +1,6 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleAlreadyDefinedException;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotUsableException;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
@@ -12,10 +11,10 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.FullRole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -43,27 +42,31 @@ public class AddRoleToAssignableRolePost extends AbstractConditionableCommand {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
FullEmote emote = (FullEmote) parameters.get(1);
String description = (String) parameters.get(2);
FullRole role = (FullRole) parameters.get(3);
Role role = (Role) parameters.get(1);
String description = null;
if (parameters.size() > 2) {
description = (String) parameters.get(2);
}
FullEmote emote = null;
if(parameters.size() > 3) {
emote = (FullEmote) parameters.get(3);
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
if(service.hasAssignableRolePlaceEmote(server, name, emote.getFakeEmote())) {
throw new AssignableRoleAlreadyDefinedException(emote, name);
// already used check via role and assignable role place name
if(!roleService.canBotInteractWithRole(role)) {
throw new AssignableRoleNotUsableException(role);
}
if(!roleService.canBotInteractWithRole(role.getRole())) {
throw new AssignableRoleNotUsableException(role, commandContext.getGuild());
}
return service.addRoleToAssignableRolePlace(server, name, role.getRole(), emote, description)
return service.addRoleToAssignableRolePlace(server, name, role, emote, description)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter emote = Parameter.builder().name("emote").type(FullEmote.class).templated(true).build();
Parameter description = Parameter.builder().name("description").type(String.class).templated(true).build();
Parameter role = Parameter.builder().name("role").type(FullRole.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName, emote, description, role);
Parameter placeName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter role = Parameter.builder().name("role").type(Role.class).templated(true).build();
Parameter rolePostName = Parameter.builder().name("displayText").type(String.class).templated(true).build();
Parameter emote = Parameter.builder().name("emote").type(FullEmote.class).optional(true).templated(true).build();
List<Parameter> parameters = Arrays.asList(placeName, role, rolePostName, emote);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("addRoleToAssignableRolePlace")

View File

@@ -39,7 +39,7 @@ public class ChangeAssignableRolePlaceConfig extends AbstractConditionableComman
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AssignableRolePlaceParameterKey configKey = (AssignableRolePlaceParameterKey) parameters.get(1);
Object parameterValue = parameters.get(2);
String parameterValue = (String) parameters.get(2);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.changeConfiguration(server, name, configKey, parameterValue)
.thenApply(aVoid -> CommandResult.fromSuccess());
@@ -49,7 +49,7 @@ public class ChangeAssignableRolePlaceConfig extends AbstractConditionableComman
public CommandConfiguration getConfiguration() {
Parameter assignableRolePlaceName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter parameterKey = Parameter.builder().name("key").type(AssignableRolePlaceParameterKey.class).templated(true).build();
Parameter parameterValue = Parameter.builder().name("value").type(Object.class).templated(true).build();
Parameter parameterValue = Parameter.builder().name("value").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(assignableRolePlaceName, parameterKey, parameterValue);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();

View File

@@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to deactive an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
@@ -30,12 +31,12 @@ public class DeactivateAssignableRolePlace extends AbstractConditionableCommand
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
service.deactivateAssignableRolePlace(server, name);
return CommandResult.fromSuccess();
return service.deactivateAssignableRolePlace(server, name)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
@@ -47,6 +48,7 @@ public class DeactivateAssignableRolePlace extends AbstractConditionableCommand
.name("deactivateAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)

View File

@@ -10,6 +10,7 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
@@ -17,6 +18,7 @@ import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to move an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
@@ -32,15 +34,16 @@ public class MoveAssignableRolePlace extends AbstractConditionableCommand {
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
TextChannel newChannel = (TextChannel) parameters.get(1);
if(!newChannel.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
placeManagementService.moveAssignableRolePlace(name, newChannel);
return CommandResult.fromSuccess();
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return placeManagementService.moveAssignableRolePlace(server, name, newChannel)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
@@ -54,6 +57,7 @@ public class MoveAssignableRolePlace extends AbstractConditionableCommand {
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.async(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)

View File

@@ -1,7 +1,8 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -9,49 +10,42 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to show how an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
* would look like in the current {@link net.dv8tion.jda.api.entities.TextChannel channel}
*/
@Component
public class TestAssignableRolePlace extends AbstractConditionableCommand {
public class RemoveAssignableRoleCondition extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
private AssignableRoleConditionService assignableRoleConditionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.testAssignableRolePlace(server, name, commandContext.getChannel())
.thenApply(aVoid -> CommandResult.fromIgnored());
Role role = (Role) parameters.get(1);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2);
assignableRoleConditionService.deleteAssignableRoleCondition(name, role, configKey);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName);
Parameter placeName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter role = Parameter.builder().name("role").type(Role.class).templated(true).build();
Parameter conditionKey = Parameter.builder().name("conditionKey").type(AssignableRoleConditionType.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("testAssignableRolePlace")
.name("removeAssignableRoleCondition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();

View File

@@ -9,7 +9,7 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,17 +36,17 @@ public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableComm
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
FullEmote emote = (FullEmote) parameters.get(1);
ARole role = (ARole) parameters.get(1);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.removeRoleFromAssignableRolePlace(server, name, emote)
return service.removeRoleFromAssignableRolePlace(server, name, role)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter emote = Parameter.builder().name("emote").type(FullEmote.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName, emote);
Parameter role = Parameter.builder().name("role").type(ARole.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName, role);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("removeRoleFromAssignableRolePlace")

View File

@@ -1,81 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.exception.EmoteNotInAssignableRolePlaceException;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
/**
* Command used to swap the positions of two {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole roles}
* within one {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class SwapAssignableRolePosition extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private EmoteService emoteService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
FullEmote firstEmote = (FullEmote) parameters.get(1);
FullEmote secondEmote = (FullEmote) parameters.get(2);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
if(emoteService.compareAEmote(firstEmote.getFakeEmote(), secondEmote.getFakeEmote())) {
return CommandResult.fromError("You cannot swap the same emote");
}
if(!service.hasAssignableRolePlaceEmote(server, name, firstEmote.getFakeEmote())) {
throw new EmoteNotInAssignableRolePlaceException(firstEmote, name);
}
if(!service.hasAssignableRolePlaceEmote(server, name, firstEmote.getFakeEmote())) {
throw new EmoteNotInAssignableRolePlaceException(secondEmote, name);
}
service.swapPositions(server, name, firstEmote, secondEmote);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
Parameter firstEmote = Parameter.builder().name("firstEmote").type(FullEmote.class).templated(true).build();
Parameter secondEmote = Parameter.builder().name("secondEmote").type(FullEmote.class).templated(true).build();
List<Parameter> parameters = Arrays.asList(rolePostName, firstEmote, secondEmote);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("swapAssignableRolePosition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -0,0 +1,87 @@
package dev.sheldan.abstracto.assignableroles.condition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleMinLevelModel;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleMinLevelResult;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleMinLevelDisplay;
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.service.ConditionService;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class AssignableRoleMinimumLevelConditionImpl implements AssignableRoleConditionEvaluator {
private final String conditionName = "HAS_LEVEL";
private final String userIdParameter = "userId";
private final String levelParameter = "level";
@Autowired
private ConditionService conditionService;
@Override
public boolean fulfillsCondition(AssignableRoleCondition conditionDefinition, AUserInAServer aUserInAServer) {
Integer level = parseLevel(conditionDefinition);
Map<String, Object> parameters = new HashMap<>();
parameters.put(userIdParameter, aUserInAServer.getUserInServerId());
parameters.put(levelParameter, level);
ConditionContextInstance contextInstance = ConditionContextInstance
.builder()
.conditionName(conditionName)
.parameters(parameters)
.build();
return conditionService.checkConditions(contextInstance);
}
@Override
public boolean usableValue(String value) {
try {
parseLevelValue(value);
return true;
} catch (Exception exception) {
return false;
}
}
private Integer parseLevel(AssignableRoleCondition conditionDefinition) {
return parseLevelValue(conditionDefinition.getConditionValue());
}
private int parseLevelValue(String value) {
return Integer.parseInt(value);
}
@Override
public AssignableRolePlaceConditionModel createNotificationModel(AssignableRoleCondition conditionDefinition, Role role) {
Integer level = parseLevel(conditionDefinition);
AssignableRoleMinLevelModel model = AssignableRoleMinLevelModel
.builder()
.minLevel(level)
.roleDisplay(RoleDisplay.fromRole(role))
.build();
return AssignableRoleMinLevelResult
.builder()
.model(model)
.build();
}
@Override
public AssignableRoleConditionDisplay getConditionDisplay(AssignableRoleCondition conditionDefinition) {
return new AssignableRoleMinLevelDisplay(Integer.parseInt(conditionDefinition.getConditionValue()));
}
@Override
public boolean handlesCondition(AssignableRoleConditionType type) {
return AssignableRoleConditionType.MIN_LEVEL.equals(type);
}
}

View File

@@ -1,47 +0,0 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlacePostManagementService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageDeletedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.listener.MessageDeletedModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class AssignablePostDeletedListener implements AsyncMessageDeletedListener {
@Autowired
private AssignableRolePlacePostManagementService service;
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
/**
* This method deletes one individual {@link AssignableRolePlacePost post}, because its message has been deleted
* @param model The {@link MessageDeletedModel message} containing the {@link CachedMessage cachedMessage} which was deleted
*/
@Override
public DefaultListenerResult execute(MessageDeletedModel model) {
Optional<AssignableRolePlacePost> messageOptional = service.findByMessageIdOptional(model.getCachedMessage().getMessageId());
messageOptional.ifPresent(post -> {
AssignableRolePlace assignablePlace = post.getAssignablePlace();
log.info("Post {} has been deleted in server {} in channel {}, we are removing a post from place {}.",
post.getId(), model.getServerId(), model.getCachedMessage().getChannelId(), assignablePlace.getKey());
post.getAssignableRoles().forEach(assignableRole -> assignableRole.setAssignableRolePlacePost(null));
assignablePlace.getMessagePosts().remove(post);
});
return DefaultListenerResult.PROCESSED;
}
}

View File

@@ -1,175 +0,0 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleServiceBean;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlacePostManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.listener.ReactionAddedModel;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.ReactionService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.MessageReaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class AssignablePostReactionAdded implements AsyncReactionAddedListener {
@Autowired
private AssignableRolePlacePostManagementService service;
@Autowired
private AssignableRoleServiceBean assignableRoleServiceBean;
@Autowired
private EmoteService emoteService;
@Autowired
private AssignableRolePlaceService assignableRolePlaceService;
@Autowired
private AssignedRoleUserManagementService assignedRoleUserManagementService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private AssignablePostReactionAdded self;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignableRoleManagementService assignableRoleManagementService;
@Autowired
private ReactionService reactionService;
@Autowired
private MemberService memberService;
/**
* Iterates over all {@link AssignableRole assignableRoles} of the post and checks which {@link AssignableRole assignableRole}
* is identified by the added {@link MessageReaction reaction}. If there is no valid reaction, the {@link net.dv8tion.jda.api.entities.MessageReaction reaction}
* will be removed again. In case the {@link AssignableRolePlace place} is configured to have unique roles, this will remove the existing
* {@link net.dv8tion.jda.api.entities.MessageReaction reaction} and the assigned {@link net.dv8tion.jda.api.entities.Role role}.
* Afterwards the appropriate {@link net.dv8tion.jda.api.entities.Role role} will be added and the update
* will be stored in the database.
* @param assignablePlacePost The {@link AssignableRolePlacePost post} onto which the {@link MessageReaction reaction} was added to
* @param model The {@link ReactionAddedModel model} containing information about who added which reaction where
*/
private void addAppropriateRoles(AssignableRolePlacePost assignablePlacePost, ReactionAddedModel model) {
boolean validReaction = false;
AssignableRolePlace assignableRolePlace = assignablePlacePost.getAssignablePlace();
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (AssignableRole assignableRole : assignablePlacePost.getAssignableRoles()) {
log.debug("Checking emote {} if it was reaction for assignable role place.", assignableRole.getEmote().getId());
if (emoteService.isReactionEmoteAEmote(model.getReaction().getReactionEmote(), assignableRole.getEmote())) {
if(assignableRolePlace.getUniqueRoles()) {
log.debug("Assignable role place {} has unique roles configured. Removing existing reactions and roles.", assignableRolePlace.getId());
Optional<AssignedRoleUser> byUserInServer = assignedRoleUserManagementService.findByUserInServerOptional(model.getUserReacting());
byUserInServer.ifPresent(user -> futures.add(assignableRolePlaceService.removeExistingReactionsAndRoles(assignableRolePlace, user)));
}
Long assignableRoleId = assignableRole.getId();
log.info("User added {} reaction {} and gets assignable role {} in server {}.", model.getUserReacting().getUserId(), assignableRole.getEmote().getId(), assignableRoleId, model.getServerId());
CompletableFuture<Void> roleAdditionFuture = assignableRoleServiceBean.assignAssignableRoleToUser(assignableRoleId, model.getUserReacting());
futures.add(CompletableFuture.allOf(roleAdditionFuture));
validReaction = true;
break;
}
}
if(!validReaction) {
log.debug("Reaction was not found in the configuration of assignable role place {}, removing reaction.", assignableRolePlace.getId());
futures.add(reactionService.removeReactionFromMessage(model.getReaction(), model.getMessage(), model.getMemberReacting().getUser()));
}
Long assignableRolePlaceId = assignableRolePlace.getId();
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
self.updateStoredAssignableRoles(assignableRolePlaceId, model.getUserReacting(), model.getReaction())
).exceptionally(throwable -> {
log.error("Failed to add role or remove emote for assignable role place {}.", assignableRolePlaceId, throwable);
return null;
});
}
/**
* Persists the {@link AssignableRole role} changes for the user who added a reaction in the database
* @param assignableRolePlaceId The ID of the {@link AssignableRolePlace place}
* @param serverUser The {@link ServerUser serverUser} who added the {@link net.dv8tion.jda.api.entities.MessageReaction reaction}
* @param reaction The {@link CachedReaction reaction} wich was added
*/
@Transactional
public void updateStoredAssignableRoles(Long assignableRolePlaceId, ServerUser serverUser, MessageReaction reaction) {
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(assignableRolePlaceId);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(serverUser);
if(place.getUniqueRoles()) {
log.debug("Assignable role place {} has unique roles. Deleting all existing references.", assignableRolePlaceId);
assignableRoleServiceBean.clearAllRolesOfUserInPlace(place, userInAServer);
}
AssignableRole role = assignableRoleManagementService.getRoleForReactionEmote(reaction.getReactionEmote(), place);
log.info("Adding role to assignable role {} to user {} in server {}.", role.getId(), userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
assignableRoleServiceBean.addRoleToUser(role.getId(), userInAServer);
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
/**
* Determines if the {@link net.dv8tion.jda.api.entities.Message message} a reaction was added to, belongs to a
* {@link AssignableRolePlacePost post}.
* If the {@link AssignableRolePlacePost post} belong to an inactive {@link AssignableRolePlace place} this method
* will automatically remove the reaction, self reactions are ignored. Otherwise the logic according to the configuration
* of the {@link AssignableRolePlace place} will be executed.
* @param model The {@link ReactionAddedModel message} which contains information about the added reaction
*/
@Override
public DefaultListenerResult execute(ReactionAddedModel model) {
MessageReaction reaction = model.getReaction();
Optional<AssignableRolePlacePost> messageOptional = service.findByMessageIdOptional(model.getMessage().getMessageId());
if(messageOptional.isPresent()) {
AssignableRolePlacePost assignablePlacePost = messageOptional.get();
if(reaction.isSelf()) {
log.info("Ignoring self reaction on assignable role post in server {}.", model.getServerId());
return DefaultListenerResult.IGNORED;
}
Long assignableRolePlacePostId = assignablePlacePost.getId();
if(assignablePlacePost.getAssignablePlace().getActive()) {
log.info("User {} added reaction to assignable role place {} in server {}. Handling added event.", model.getUserReacting().getUserId(), assignablePlacePost.getId(), model.getServerId());
addAppropriateRoles(assignablePlacePost, model);
} else {
reactionService.removeReactionFromMessage(model.getReaction(), model.getMessage()).exceptionally(throwable -> {
log.error("Failed to remove reaction on place post {} because place is inactive.", assignableRolePlacePostId, throwable);
return null;
});
log.debug("Reaction for assignable place {} in sever {} was added, but place is inactive.", assignablePlacePost.getAssignablePlace().getKey(), model.getServerId());
}
}
return DefaultListenerResult.PROCESSED;
}
}

View File

@@ -1,81 +0,0 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlacePostManagementService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionRemovedListener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.listener.ReactionRemovedModel;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@Slf4j
public class AssignablePostReactionRemoved implements AsyncReactionRemovedListener {
@Autowired
private AssignableRolePlacePostManagementService service;
@Autowired
private EmoteService emoteService;
@Autowired
private RoleService roleService;
@Autowired
private AssignableRoleService assignableRoleService;
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
/**
* Determines if the {@link net.dv8tion.jda.api.entities.Message message} a reaction was removed from, belongs to a
* {@link AssignableRolePlacePost post}.
* If the {@link AssignableRolePlacePost post} belong to an inactive {@link AssignableRolePlace place} this method ignores the removal.
* Otherwise the logic according to the configuration
* of the {@link AssignableRolePlace place} will be executed.
* @param model The {@link ReactionRemovedModel model} containing the information which reaction was placed where
*/
@Override
public DefaultListenerResult execute(ReactionRemovedModel model) {
CachedMessage message = model.getMessage();
Optional<AssignableRolePlacePost> messageOptional = service.findByMessageIdOptional(message.getMessageId());
if(messageOptional.isPresent()) {
AssignableRolePlacePost assignablePlacePost = messageOptional.get();
if(assignablePlacePost.getAssignablePlace().getActive()) {
assignablePlacePost.getAssignableRoles().forEach(assignableRole -> {
if(emoteService.isReactionEmoteAEmote(model.getReaction().getReactionEmote(), assignableRole.getEmote())) {
Long assignableRoleId = assignableRole.getId();
log.info("Removing assignable role {} for user {} in server {} from assignable role place {}.", assignableRoleId,
model.getUserRemoving().getUserId(), model.getServerId(), assignablePlacePost.getAssignablePlace().getId());
assignableRoleService.fullyRemoveAssignableRoleFromUser(assignableRole, model.getUserRemoving()).exceptionally(throwable -> {
log.error("Failed to remove assignable role {} from user {} in server {}.", assignableRoleId, model.getUserRemoving().getUserId(), model.getServerId(), throwable);
return null;
});
}
});
return DefaultListenerResult.PROCESSED;
} else {
log.debug("Reaction for assignable place {} in sever {} was added, but place is inactive.", assignablePlacePost.getAssignablePlace().getKey(), model.getServerId());
return DefaultListenerResult.PROCESSED;
}
} else {
return DefaultListenerResult.IGNORED;
}
}
}

View File

@@ -0,0 +1,217 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
import dev.sheldan.abstracto.assignableroles.model.AssignableRolePlacePayload;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRoleSuccessNotificationModel;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionServiceBean;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceServiceBean;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementServiceBean;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import lombok.extern.slf4j.Slf4j;
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.events.interaction.ButtonClickEvent;
import net.dv8tion.jda.api.interactions.components.ButtonInteraction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
@Slf4j
public class AssignableRoleButtonClickedListener implements ButtonClickedListener {
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private RoleService roleService;
@Autowired
private AssignableRoleButtonClickedListener self;
@Autowired
private InteractionService interactionService;
@Autowired
private AssignableRoleService assignableRoleService;
@Autowired
private AssignedRoleUserManagementServiceBean assignedRoleUserManagementServiceBean;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignableRoleConditionServiceBean assignableRoleConditionServiceBean;
@Override
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
ButtonClickEvent event = model.getEvent();
AssignableRolePlacePayload payload = (AssignableRolePlacePayload) model.getDeserializedPayload();
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
if(event.getGuild() != null && event.getMember() != null) {
Guild guild = event.getGuild();
List<Role> removedRoles = new ArrayList<>();
Role roleById = guild.getRoleById(payload.getRoleId());
Optional<AssignableRole> assignableRoleOptional = place
.getAssignableRoles()
.stream()
.filter(assignableRole -> assignableRole.getRole().getId().equals(payload.getRoleId()))
.findFirst();
if(!assignableRoleOptional.isPresent()) {
throw new AssignableRoleNotFoundException(payload.getRoleId());
}
if(roleById != null) {
boolean memberHasRole = event
.getMember()
.getRoles()
.stream()
.anyMatch(memberRole -> memberRole.getIdLong() == payload.getRoleId());
if(!memberHasRole) {
AssignableRole assignableRole = assignableRoleOptional.get();
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember());
if(!assignableRole.getConditions().isEmpty()) {
AssignableRoleConditionResult conditionResult =
assignableRoleConditionServiceBean.evaluateConditions(assignableRole.getConditions(), aUserInAServer, roleById);
if(!conditionResult.getFulfilled()) {
self.notifyUserAboutConditionFail(model, event.getInteraction(), conditionResult.getModel());
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
}
CompletableFuture<Void> removalFuture;
if(place.getUniqueRoles()) {
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementServiceBean.findByUserInServerOptional(aUserInAServer);
if(assignedRoleUserOptional.isPresent()) {
AssignedRoleUser roleUser = assignedRoleUserOptional.get();
List<Role> rolesToRemove = roleUser
.getRoles()
.stream()
.filter(roleOfUser -> roleOfUser.getAssignablePlace().equals(place))
.map(roleOfUser -> guild.getRoleById(roleOfUser.getRole().getId()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
removedRoles.addAll(rolesToRemove);
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
rolesToRemove.forEach(roleToRemove -> removalFutures.add(roleService.removeRoleFromUserAsync(event.getMember(), roleToRemove)));
removalFuture = new CompletableFutureList<>(removalFutures).getMainFuture();
} else {
removalFuture = CompletableFuture.completedFuture(null);
}
} else {
removalFuture = CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> roleAdditionFuture = roleService.addRoleToMemberAsync(event.getMember(), roleById);
CompletableFuture.allOf(removalFuture, roleAdditionFuture).whenComplete((unused, throwable) -> {
if(throwable != null) {
log.error("Failed to either add or remove roles for assignable role place {} in server {}.", payload.getPlaceId(), guild.getIdLong());
}
if(!roleAdditionFuture.isCompletedExceptionally()) {
log.info("Added role {} to member {} in server {} for assignable role interaction {} on component {}.",
roleById.getId(), event.getMember().getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
self.notifyUser(model, true, roleById, event.getInteraction(), removedRoles).thenAccept(unused1 -> {
log.info("Persisting adding assignable role update for user {} in server {} of role {}.", event.getMember().getIdLong(), guild.getIdLong(), roleById.getId());
self.persistAssignableUser(event.getMember(), payload, false);
});
}
});
} else {
roleService.removeRoleFromUserAsync(event.getMember(), roleById)
.thenAccept(unused -> {
self.notifyUser(model, false, roleById, event.getInteraction(), new ArrayList<>());
log.info("Removed role {} from member {} in server {} for assignable role interaction {} on component {}.",
roleById.getId(), event.getMember().getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
}).thenAccept(unused -> {
log.info("Persisting remove assignable role update for user {} in server {} of role {}.", event.getMember().getIdLong(), guild.getIdLong(), roleById.getId());
self.persistAssignableUser(event.getMember(), payload, true);
});
}
} else {
log.warn("Role {} is not available to be assigned in assignable role place {} in server {}. Component {} failed.",
payload.getRoleId(), payload.getPlaceId(), guild.getIdLong(), event.getComponentId());
throw new AssignableRoleNotFoundException(payload.getRoleId());
}
}
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
@Transactional
public void persistAssignableUser(Member member, AssignableRolePlacePayload payload, boolean removeRole){
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
if(place.getUniqueRoles() && !removeRole) {
assignableRoleService.clearAllRolesOfUserInPlace(place, aUserInAServer);
}
Optional<AssignableRole> assignableRoleOptional = place
.getAssignableRoles()
.stream()
.filter(assignableRole -> assignableRole.getRole().getId().equals(payload.getRoleId()))
.findFirst();
if(assignableRoleOptional.isPresent()) {
if(removeRole) {
assignableRoleService.removeRoleFromUser(assignableRoleOptional.get(), aUserInAServer);
} else {
assignableRoleService.addRoleToUser(assignableRoleOptional.get(), aUserInAServer);
}
}
}
@Transactional
public CompletableFuture<Void> notifyUser(ButtonClickedListenerModel model, boolean roleAdded, Role role, ButtonInteraction buttonInteraction, List<Role> removedRoles) {
AssignableRoleSuccessNotificationModel notificationModel = AssignableRoleSuccessNotificationModel
.builder()
.added(roleAdded)
.removedRoles(removedRoles)
.role(role)
.build();
return FutureUtils.toSingleFutureGeneric(
interactionService.sendMessageToInteraction("assignable_role_success_notification", notificationModel, buttonInteraction.getHook())) ;
}
@Transactional
public CompletableFuture<Void> notifyUserAboutConditionFail(ButtonClickedListenerModel model, ButtonInteraction buttonInteraction,
AssignableRolePlaceConditionModel conditionModel) {
return FutureUtils.toSingleFutureGeneric(
interactionService.sendMessageToInteraction("assignable_role_condition_notification", conditionModel, buttonInteraction.getHook())) ;
}
@Override
public Boolean handlesEvent(ButtonClickedListenerModel model) {
return model.getOrigin().equals(AssignableRolePlaceServiceBean.ASSIGNABLE_ROLE_COMPONENT_ORIGIN);
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.assignableroles.model;
import dev.sheldan.abstracto.core.models.template.button.ButtonPayload;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRolePlacePayload implements ButtonPayload {
private Long placeId;
private Long roleId;
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface AssignableRoleConditionRepository extends JpaRepository<AssignableRoleCondition, Long> {
Optional<AssignableRoleCondition> findByAssignableRoleAndType(AssignableRole assignableRole, AssignableRoleConditionType type);
}

View File

@@ -1,12 +0,0 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Repository to manage the access to the table managed by {@link AssignableRolePlacePost posts}
*/
@Repository
public interface AssignableRolePlacePostRepository extends JpaRepository<AssignableRolePlacePost, Long> {
}

View File

@@ -0,0 +1,125 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.condition.AssignableRoleConditionEvaluator;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionAlreadyExistsException;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionValueNotUsableException;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionDoesNotExistException;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleConditionManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Component
public class AssignableRoleConditionServiceBean implements AssignableRoleConditionService {
@Autowired
private List<AssignableRoleConditionEvaluator> assignableRoleConditionEvaluators;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private AssignableRoleService assignableRoleService;
@Autowired
private AssignableRoleConditionManagementService assignableRoleConditionManagementService;
@Override
public AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, Member member, Role role) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
return evaluateConditions(conditions, aUserInAServer, role);
}
@Override
public AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, AUserInAServer aUserInAServer, Role role) {
for (AssignableRoleCondition condition : conditions) {
if(assignableRoleConditionEvaluators != null) {
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(condition.getType());
if(evaluatorOptional.isPresent()) {
AssignableRoleConditionEvaluator evaluator = evaluatorOptional.get();
if(!evaluator.fulfillsCondition(condition, aUserInAServer)) {
return AssignableRoleConditionResult.fromFail(condition.getType(), evaluator.createNotificationModel(condition, role));
}
}
}
}
return AssignableRoleConditionResult.fromSuccess();
}
private Optional<AssignableRoleConditionEvaluator> findEvaluatorForCondition(AssignableRoleConditionType type) {
return assignableRoleConditionEvaluators
.stream()
.filter(assignableRoleConditionEvaluator -> assignableRoleConditionEvaluator.handlesCondition(type))
.findFirst();
}
@Override
public AssignableRoleCondition createAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type, String value) {
AServer server = serverManagementService.loadServer(role.getGuild());
AssignableRolePlace place = assignableRolePlaceManagementService.findByServerAndKey(server, placeName);
AssignableRole assignableRole = assignableRoleService.getAssignableRoleInPlace(place, role);
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(type);
if(!evaluatorOptional.isPresent()) {
throw new AssignableRoleConditionDoesNotExistException();
}
evaluatorOptional.ifPresent(evaluator -> {
boolean valueUsable = evaluator.usableValue(value);
if(!valueUsable) {
throw new AssignableRoleConditionValueNotUsableException();
}
});
if(assignableRoleConditionManagementService.findAssignableRoleCondition(assignableRole, type).isPresent()) {
throw new AssignableRoleConditionAlreadyExistsException();
}
return assignableRoleConditionManagementService.createAssignableRoleCondition(assignableRole, type, value);
}
@Override
public void deleteAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type) {
AServer server = serverManagementService.loadServer(role.getGuild());
AssignableRolePlace place = assignableRolePlaceManagementService.findByServerAndKey(server, placeName);
AssignableRole assignableRole = assignableRoleService.getAssignableRoleInPlace(place, role);
Optional<AssignableRoleCondition> existingCondition = assignableRoleConditionManagementService.findAssignableRoleCondition(assignableRole, type);
if(!existingCondition.isPresent()) {
throw new AssignableRoleConditionDoesNotExistException();
}
existingCondition.ifPresent(condition -> assignableRoleConditionManagementService.deleteAssignableRoleCondition(condition));
}
@Override
public List<AssignableRoleConditionDisplay> getConditionDisplays(List<AssignableRoleCondition> conditions) {
return conditions.stream().map(condition -> {
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(condition.getType());
if(evaluatorOptional.isPresent()) {
AssignableRoleConditionEvaluator evaluator = evaluatorOptional.get();
return evaluator.getConditionDisplay(condition);
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
@@ -9,19 +10,21 @@ import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUser
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.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@@ -73,32 +76,27 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
log.info("Assigning role {} to member {} in server {}.", assignableRoleId, member.getId(), member.getGuild().getId());
return roleService.addRoleToMemberFuture(member, role.getRole());
}
@Override
public CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, ServerUser serverUser) {
return memberService.retrieveMemberInServer(serverUser).thenCompose(member -> assignAssignableRoleToUser(assignableRoleId, member));
return roleService.addRoleToMemberAsync(member, role.getRole());
}
@Override
public void clearAllRolesOfUserInPlace(AssignableRolePlace place, AUserInAServer userInAServer) {
AssignedRoleUser user = assignedRoleUserManagementServiceBean.findByUserInServer(userInAServer);
log.info("Clearing all {} assignable roles in place {} for user {} in server {}.",
user.getRoles().size(), place.getId(), userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
user.getRoles().forEach(assignableRole -> {
if(assignableRole.getAssignablePlace().equals(place)) {
assignableRole.getAssignedUsers().remove(user);
}
Optional<AssignedRoleUser> userOptional = assignedRoleUserManagementServiceBean.findByUserInServerOptional(userInAServer);
userOptional.ifPresent(assignedRoleUser -> {
log.info("Clearing all {} assignable roles in place {} for user {} in server {}.",
assignedRoleUser.getRoles().size(), place.getId(), userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
assignedRoleUser.getRoles().forEach(assignableRole -> {
if(assignableRole.getAssignablePlace().equals(place)) {
assignableRole.getAssignedUsers().remove(assignedRoleUser);
}
});
assignedRoleUser.getRoles().removeIf(assignableRole -> assignableRole.getAssignablePlace().equals(place));
});
user.getRoles().removeIf(assignableRole -> assignableRole.getAssignablePlace().equals(place));
}
@Override
public CompletableFuture<Void> fullyAssignAssignableRoleToUser(Long assignableRoleId, Member toAdd) {
return this.assignAssignableRoleToUser(assignableRoleId, toAdd).thenAccept(aVoid ->
self.addRoleToUser(assignableRoleId, toAdd)
);
if(!userOptional.isPresent()) {
log.info("User {} was not yet stored as an assignable role user in server {} - nothing to clear.",
userInAServer.getUserReference().getId(), place.getServer().getId());
}
}
@Override
@@ -115,30 +113,6 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
return self.removeAssignableRoleFromUser(role, member);
}
@Override
public CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
Long assignableRoleId = assignableRole.getId();
return memberService.getMemberInServerAsync(aUserInAServer).thenCompose(member ->
self.removeAssignableRoleFromUser(assignableRoleId, member)
);
}
@Override
public CompletableFuture<Void> fullyRemoveAssignableRoleFromUser(AssignableRole assignableRole, ServerUser serverUser) {
Long assignableRoleId = assignableRole.getId();
return memberService.retrieveMemberInServer(serverUser).thenCompose(member ->
this.removeAssignableRoleFromUser(assignableRole, member)
.thenAccept(aVoid -> self.persistRoleRemovalFromUser(assignableRoleId, member))
);
}
@Transactional
@Override
public void addRoleToUser(Long assignableRoleId, AUserInAServer aUserInAServer) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
addRoleToUser(role, aUserInAServer);
}
@Override
public void addRoleToUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
log.info("Persisting storing adding assignable role {} to user {} in server {}.",
@@ -153,39 +127,24 @@ public class AssignableRoleServiceBean implements AssignableRoleService {
assignedRoleUserManagementServiceBean.removeAssignedRoleFromUser(assignableRole, aUserInAServer);
}
/**
* Adds the given {@link AssignableRole assignableRole} identified by the ID to the given {@link Member member}
* @param assignableRoleId The ID of the {@link AssignableRole} to be added to the {@link Member member}
* @param member The {@link Member member} to add the {@link AssignableRole role} to
*/
@Transactional
public void addRoleToUser(Long assignableRoleId, Member member) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
addRoleToUser(role, aUserInAServer);
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Role role) {
return getAssignableRoleInPlace(place, role.getIdLong());
}
/**
* Removes the given {@link AssignableRole assignableRole} identified by the ID from the given {@link AUserInAServer user}
* @param assignableRoleId The ID of the {@link AssignableRole} to be removed from the {@link Member member}
* @param aUserInAServer The {@link AUserInAServer user} to remove the {@link AssignableRole role} from
*/
@Transactional
public void removeRoleFromUser(Long assignableRoleId, AUserInAServer aUserInAServer) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
removeRoleFromUser(role, aUserInAServer);
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, ARole role) {
return getAssignableRoleInPlace(place, role.getId());
}
/**
* Stores the removal of an {@link AssignableRole assignableRole} from a {@link Member member} in the database
* @param assignableRoleId The ID of the {@link AssignableRole} to be removed from the {@link Member member}
* @param member The {@link Member member} which should get the {@link AssignableRole role} removed
*/
@Transactional
public void persistRoleRemovalFromUser(Long assignableRoleId, Member member) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
removeRoleFromUser(role, aUserInAServer);
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Long roleId) {
for (AssignableRole assignableRole : place.getAssignableRoles()) {
if (assignableRole.getRole().getId().equals(roleId)) {
return assignableRole;
}
}
throw new AssignableRoleNotFoundException(roleId);
}
@PostConstruct

View File

@@ -0,0 +1,39 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleConditionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class AssignableRoleConditionManagementServiceBean implements AssignableRoleConditionManagementService {
@Autowired
private AssignableRoleConditionRepository repository;
@Override
public AssignableRoleCondition createAssignableRoleCondition(AssignableRole assignableRole, AssignableRoleConditionType type, String value) {
AssignableRoleCondition condition = AssignableRoleCondition
.builder()
.assignableRole(assignableRole)
.type(type)
.conditionValue(value)
.build();
assignableRole.getConditions().add(condition);
return repository.save(condition);
}
@Override
public void deleteAssignableRoleCondition(AssignableRoleCondition condition) {
repository.delete(condition);
}
@Override
public Optional<AssignableRoleCondition> findAssignableRoleCondition(AssignableRole role, AssignableRoleConditionType type) {
return repository.findByAssignableRoleAndType(role, type);
}
}

View File

@@ -1,19 +1,17 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlaceNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleRepository;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.MessageReaction;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -30,9 +28,6 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
@Autowired
private RoleManagementService roleManagementService;
@Autowired
private AssignableRolePlacePostManagementService postManagementService;
@Autowired
private AssignableRoleRepository repository;
@@ -40,45 +35,23 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
private EmoteService emoteService;
@Override
public AssignableRole addRoleToPlace(AssignableRolePlace place, AEmote emote, ARole role, String description, AssignableRolePlacePost post) {
Integer maxPosition = place.getAssignableRoles().stream().map(AssignableRole::getPosition).max(Integer::compareTo).orElse(0);
if(!place.getAssignableRoles().isEmpty()) {
maxPosition += 1;
}
public AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload) {
ARole arole = roleManagementService.findRole(role.getIdLong());
AssignableRole roleToAdd = AssignableRole
.builder()
.assignablePlace(place)
.emote(emote)
.role(role)
.requiredLevel(0)
.emoteMarkdown(emote != null ? emote.getEmoteRepr() : null)
.role(arole)
.componentPayload(componentPayload)
.server(place.getServer())
.position(maxPosition)
.description(description)
.assignableRolePlacePost(post)
.build();
place.getAssignableRoles().add(roleToAdd);
log.info("Adding role {} to assignable role place {}. There are now {} roles.", role.getId(), place.getId(), place.getAssignableRoles().size());
return roleToAdd;
}
@Override
public AssignableRole addRoleToPlace(Long placeId, Integer emoteId, Long roleId, String description, Long messageId) {
AssignableRolePlace place = rolePlaceManagementService.findByPlaceIdOptional(placeId).orElseThrow(() -> new AssignableRolePlaceNotFoundException(placeId));
AEmote emote = emoteManagementService.loadEmote(emoteId);
ARole role = roleManagementService.findRole(roleId);
AssignableRolePlacePost post = postManagementService.findByMessageId(messageId);
AssignableRole assignableRole = addRoleToPlace(place, emote, role, description, post);
post.getAssignableRoles().add(assignableRole);
return assignableRole;
}
@Override
public AssignableRole addRoleToPlace(Long placeId, Integer emoteId, Long roleId, String description) {
AssignableRolePlace place = rolePlaceManagementService.findByPlaceIdOptional(placeId).orElseThrow(() -> new AssignableRolePlaceNotFoundException(placeId));
AEmote emote = emoteManagementService.loadEmote(emoteId);
ARole role = roleManagementService.findRole(roleId);
return addRoleToPlace(place, emote, role, description, null);
}
@Override
public AssignableRole getByAssignableRoleId(Long assignableRoleId) {
@@ -86,26 +59,8 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
}
@Override
public AssignableRole getRoleForReactionEmote(CachedEmote cachedEmote, AssignableRolePlace assignableRolePlace) {
for (AssignableRolePlacePost post : assignableRolePlace.getMessagePosts()) {
for (AssignableRole assignableRole : post.getAssignableRoles()) {
if (emoteService.compareCachedEmoteWithAEmote(cachedEmote, assignableRole.getEmote())) {
return assignableRole;
}
}
}
throw new AbstractoRunTimeException("Role for reaction was not found.");
public void deleteAssignableRole(AssignableRole assignableRole) {
repository.delete(assignableRole);
}
@Override
public AssignableRole getRoleForReactionEmote(MessageReaction.ReactionEmote cachedEmote, AssignableRolePlace assignableRolePlace) {
for (AssignableRolePlacePost post : assignableRolePlace.getMessagePosts()) {
for (AssignableRole assignableRole : post.getAssignableRoles()) {
if (emoteService.isReactionEmoteAEmote(cachedEmote, assignableRole.getEmote())) {
return assignableRole;
}
}
}
throw new AbstractoRunTimeException("Role for reaction was not found.");
}
}

View File

@@ -39,8 +39,7 @@ public class AssignableRolePlaceManagementServiceBean implements AssignableRoleP
@Override
public AssignableRolePlace findByServerAndKey(AServer server, String name) {
// todo use other exception or adapt exception
return repository.findByServerAndKey(server, name).orElseThrow(() -> new AssignableRolePlaceNotFoundException(0L));
return repository.findByServerAndKey(server, name).orElseThrow(AssignableRolePlaceNotFoundException::new);
}
@Override
@@ -50,7 +49,7 @@ public class AssignableRolePlaceManagementServiceBean implements AssignableRoleP
@Override
public AssignableRolePlace findByPlaceId(Long id) {
return findByPlaceIdOptional(id).orElseThrow(() -> new AssignableRolePlaceNotFoundException(id));
return findByPlaceIdOptional(id).orElseThrow(AssignableRolePlaceNotFoundException::new);
}
@Override

View File

@@ -1,41 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlacePostNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRolePlacePostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class AssignableRolePlacePostManagementServiceBean implements AssignableRolePlacePostManagementService {
@Autowired
private AssignableRolePlacePostRepository repository;
@Override
public Optional<AssignableRolePlacePost> findByMessageIdOptional(Long messageId) {
return repository.findById(messageId);
}
@Override
public AssignableRolePlacePost findByMessageId(Long messageId) {
return findByMessageIdOptional(messageId).orElseThrow(() -> new AssignableRolePlacePostNotFoundException(messageId));
}
@Override
public AssignableRolePlacePost createAssignableRolePlacePost(AssignableRolePlace updatedPlace, Long messageId) {
AssignableRolePlacePost post = AssignableRolePlacePost
.builder()
.id(messageId)
.usedChannel(updatedPlace.getChannel())
.server(updatedPlace.getServer())
.assignablePlace(updatedPlace)
.build();
updatedPlace.getMessagePosts().add(post);
return post;
}
}

View File

@@ -1,2 +1,2 @@
abstracto.featureFlags.emoteTracking.featureName=emoteTracking
abstracto.featureFlags.emoteTracking.enabled=false
abstracto.featureFlags.assignableRole.featureName=assignableRole
abstracto.featureFlags.assignableRole.enabled=false

View File

@@ -6,83 +6,78 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<property name="experienceModule" value="(SELECT id FROM module WHERE name = 'assignableRoles')"/>
<property name="experienceFeature" value="(SELECT id FROM feature WHERE key = 'assignableRole')"/>
<property name="assignableRoleModule" value="(SELECT id FROM module WHERE name = 'assignableRoles')"/>
<property name="assignableRoleFeature" value="(SELECT id FROM feature WHERE key = 'assignableRole')"/>
<changeSet author="Sheldan" id="assignable_roles-commands">
<insert tableName="command">
<column name="name" value="addRoleToAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="setupAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="activateAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="deactivateAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="removeRoleFromAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="changeAssignableRolePlaceConfig"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="setAssignableRolePosition"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="swapAssignableRolePosition"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="testAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="deleteAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="createAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showAssignableRolePlaceConfig"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="editAssignableRolePlaceText"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="moveAssignableRolePlace"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showAssignableRolePlaces"/>
<column name="module_id" valueComputed="${experienceModule}"/>
<column name="feature_id" valueComputed="${experienceFeature}"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="addAssignableRoleCondition"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="removeAssignableRoleCondition"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
</changeSet>

View File

@@ -11,8 +11,8 @@
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_pkey"/>
</column>
<column name="emote_id" type="INTEGER">
<constraints nullable="false"/>
<column name="emote_markdown" type="VARCHAR(100)">
<constraints nullable="true"/>
</column>
<column name="role_id" type="BIGINT">
<constraints nullable="false"/>
@@ -23,26 +23,22 @@
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="place_post_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="description" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="required_level" type="INTEGER"/>
<column name="position" type="INTEGER">
<constraints nullable="false"/>
</column>
<column name="component_id" type="VARCHAR(100)" />
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="emote_id" baseTableName="assignable_role" constraintName="fk_assignable_role_emote" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="emote" validate="true"/>
<createIndex indexName="idx_assignable_role_role_id" tableName="assignable_role">
<column name="role_id"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="role_id" baseTableName="assignable_role" constraintName="fk_assignable_role_role" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="role" validate="true"/>
<addForeignKeyConstraint baseColumnNames="assignable_place_id" baseTableName="assignable_role" constraintName="fk_assignable_role_place" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role_place" validate="true"/>
<addForeignKeyConstraint baseColumnNames="place_post_id" baseTableName="assignable_role" constraintName="fk_assignable_role_post" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role_place_post" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="assignable_role" constraintName="fk_assignable_role_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="component_id" baseTableName="assignable_role" constraintName="fk_assignable_role_payload" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="component_payload" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_update_trigger ON assignable_role;
CREATE TRIGGER assignable_role_update_trigger BEFORE UPDATE ON assignable_role FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();

View File

@@ -0,0 +1,33 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="assignable_role_condition-table">
<createTable tableName="assignable_role_condition">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_condition_pkey"/>
</column>
<column name="type" type="VARCHAR(100)">
<constraints nullable="false"/>
</column>
<column name="assignable_role_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="condition_value" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="assignable_role_id" baseTableName="assignable_role_condition" constraintName="fk_assignable_role_condition_assignable_role"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_condition_insert_trigger ON assignable_role_condition;
CREATE TRIGGER assignable_role_condition_insert_trigger BEFORE INSERT ON assignable_role_condition FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -23,18 +23,10 @@
<column name="text" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="active" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="inline" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="unique_roles" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="auto_remove" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="message_id" type="BIGINT" />
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>

View File

@@ -1,41 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="assignable_role_place_post-table">
<createTable tableName="assignable_role_place_post">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_place_post_pkey"/>
</column>
<column name="assignable_place_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="assignable_place_id" baseTableName="assignable_role_place_post" constraintName="fk_assignable_role_place_post_place_id" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role_place" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="assignable_role_place_post" constraintName="fk_assignable_role_place_post_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="channel_id" baseTableName="assignable_role_place_post" constraintName="fk_assignable_role_place_post_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_place_post_update_trigger ON assignable_role_place_post;
CREATE TRIGGER assignable_role_place_post_update_trigger BEFORE UPDATE ON assignable_role_place_post FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS assignable_role_place_post_insert_trigger ON assignable_role_place_post;
CREATE TRIGGER assignable_role_place_post_insert_trigger BEFORE INSERT ON assignable_role_place_post FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -7,7 +7,7 @@
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="assignable_role_place.xml" relativeToChangelogFile="true"/>
<include file="assignable_role_place_post.xml" relativeToChangelogFile="true"/>
<include file="assignable_role.xml" relativeToChangelogFile="true"/>
<include file="assignable_role_condition.xml" relativeToChangelogFile="true"/>
<include file="assigned_role_user.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>