[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

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.assignableroles.condition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Role;
public interface AssignableRoleConditionEvaluator {
boolean handlesCondition(AssignableRoleConditionType type);
boolean fulfillsCondition(AssignableRoleCondition conditionDefinition, AUserInAServer aUserInAServer);
boolean usableValue(String value);
AssignableRolePlaceConditionModel createNotificationModel(AssignableRoleCondition conditionDefinition, Role role);
AssignableRoleConditionDisplay getConditionDisplay(AssignableRoleCondition conditionDefinition);
}

View File

@@ -3,11 +3,7 @@ package dev.sheldan.abstracto.assignableroles.config;
import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import lombok.Getter;
/**
* This enum is used to define the different key for which there exist properties on an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace}.
* And is used for the command parameter when changing the value of an attribute on this place.
*/
@Getter
public enum AssignableRolePlaceParameterKey implements CommandParameterKey {
INLINE, UNIQUE, AUTOREMOVE, ACTIVE
UNIQUE
}

View File

@@ -2,8 +2,9 @@ package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleAlreadyDefinedExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Role;
/**
* Exception thrown in case the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole} has already been
@@ -13,14 +14,18 @@ import dev.sheldan.abstracto.core.templating.Templatable;
public class AssignableRoleAlreadyDefinedException extends AbstractoRunTimeException implements Templatable {
private final AssignableRoleAlreadyDefinedExceptionModel model;
public AssignableRoleAlreadyDefinedException(FullEmote emote, String placeName) {
public AssignableRoleAlreadyDefinedException(Role role, String placeName) {
super("Assignable role already assigned");
this.model = AssignableRoleAlreadyDefinedExceptionModel.builder().emote(emote).placeName(placeName).build();
this.model = AssignableRoleAlreadyDefinedExceptionModel
.builder()
.roleDisplay(RoleDisplay.fromRole(role))
.placeName(placeName)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_emote_already_defined_exception";
return "assignable_role_already_defined_exception";
}
@Override

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionAlreadyExistsException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_already_present_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionDoesNotExistException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_does_not_exist_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionValueNotUsableException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_value_not_usable_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,27 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleNotFoundException extends AbstractoTemplatableException {
private final AssignableRoleNotFoundExceptionModel model;
public AssignableRoleNotFoundException(Long roleId) {
super("Role to assign is not available anymore.");
this.model = AssignableRoleNotFoundExceptionModel
.builder()
.roleId(roleId)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_not_found_exception";
}
@Override
public Object getTemplateModel() {
return this.model;
}
}

View File

@@ -2,9 +2,9 @@ package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleNotUsableExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.FullRole;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Role;
/**
* Exception thrown in case the defined {@link net.dv8tion.jda.api.entities.Role role} cannot be interacted with by the bot,
@@ -14,14 +14,17 @@ import net.dv8tion.jda.api.entities.Guild;
public class AssignableRoleNotUsableException extends AbstractoRunTimeException implements Templatable {
private final AssignableRoleNotUsableExceptionModel model;
public AssignableRoleNotUsableException(FullRole role, Guild guild) {
public AssignableRoleNotUsableException(Role role) {
super("Role is not usable as assignable role");
this.model = AssignableRoleNotUsableExceptionModel.builder().role(role).guild(guild).build();
this.model = AssignableRoleNotUsableExceptionModel
.builder()
.roleDisplay(RoleDisplay.fromRole(role))
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_role_not_usable_exception";
return "assignable_role_not_usable_exception";
}
@Override

View File

@@ -14,7 +14,10 @@ public class AssignableRolePlaceAlreadyExistsException extends AbstractoRunTimeE
public AssignableRolePlaceAlreadyExistsException(String name) {
super("Assignable role place already exists");
this.model = AssignableRolePlaceAlreadyExistsExceptionModel.builder().name(name).build();
this.model = AssignableRolePlaceAlreadyExistsExceptionModel
.builder()
.name(name)
.build();
}
@Override

View File

@@ -14,7 +14,11 @@ public class AssignableRolePlaceChannelDoesNotExistException extends AbstractoRu
public AssignableRolePlaceChannelDoesNotExistException(Long channelId, String placeName) {
super("Assignable role place channel does not exist");
this.model = AssignableRolePlaceChannelDoesNotExistExceptionModel.builder().channelId(channelId).placeName(placeName).build();
this.model = AssignableRolePlaceChannelDoesNotExistExceptionModel
.builder()
.channelId(channelId)
.placeName(placeName)
.build();
}
@Override

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRolePlaceIllegalConfigurationException extends AbstractoTemplatableException {
public AssignableRolePlaceIllegalConfigurationException() {
super("An illegal configuration key has been passed to configure the assignable role place config. Doing nothing.");
}
@Override
public String getTemplateName() {
return "assignable_role_place_illegal_configuration_key_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRolePlaceMaximumRolesException extends AbstractoTemplatableException {
public AssignableRolePlaceMaximumRolesException() {
super("The maximum amount of assignable roles have been reached.");
}
@Override
public String getTemplateName() {
return "assignable_role_place_maximum_roles_reached_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,20 +1,12 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRolePlaceNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception which is thrown in case a {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
* defined by a {@link String key} does not exist
*/
public class AssignableRolePlaceNotFoundException extends AbstractoRunTimeException implements Templatable {
private final AssignableRolePlaceNotFoundExceptionModel model;
public AssignableRolePlaceNotFoundException(Long placeId) {
public AssignableRolePlaceNotFoundException() {
super("Assignable role place not found");
this.model = AssignableRolePlaceNotFoundExceptionModel.builder().placeId(placeId).build();
}
@Override
@@ -24,6 +16,6 @@ public class AssignableRolePlaceNotFoundException extends AbstractoRunTimeExcept
@Override
public Object getTemplateModel() {
return model;
return new Object();
}
}

View File

@@ -1,29 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRolePlacePostNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception which is thrown, in case the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost post}
* was not found via its message ID
*/
public class AssignableRolePlacePostNotFoundException extends AbstractoRunTimeException implements Templatable {
private final AssignableRolePlacePostNotFoundExceptionModel model;
public AssignableRolePlacePostNotFoundException(Long messageId) {
super("Assignable place post not found.");
this.model = AssignableRolePlacePostNotFoundExceptionModel.builder().messageId(messageId).build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_post_not_found_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -15,7 +15,10 @@ public class AssignedUserNotFoundException extends AbstractoRunTimeException imp
public AssignedUserNotFoundException(AUserInAServer userInAServer) {
super("Assigned user was not found");
this.model = AssignedUserNotFoundExceptionModel.builder().aUserInAServer(userInAServer).build();
this.model = AssignedUserNotFoundExceptionModel
.builder()
.userId(userInAServer.getUserReference().getId())
.build();
}
@Override

View File

@@ -1,31 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.EmoteNotInAssignableRolePlaceExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception which is thrown in case a given {@link dev.sheldan.abstracto.core.models.database.AEmote} was not found
* in the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace}, when it was tried to switch
* or move the emotes around.
*/
public class EmoteNotInAssignableRolePlaceException extends AbstractoRunTimeException implements Templatable {
private final EmoteNotInAssignableRolePlaceExceptionModel model;
public EmoteNotInAssignableRolePlaceException(FullEmote emote, String placeName) {
super("Emote not found in assignable role place");
this.model = EmoteNotInAssignableRolePlaceExceptionModel.builder().emote(emote).placeName(placeName).build();
}
@Override
public String getTemplateName() {
return "emote_not_in_assignable_role_place_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -0,0 +1,38 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleConditionResult {
private Boolean fulfilled;
private AssignableRoleConditionType causingCondition;
private AssignableRolePlaceConditionModel model;
public static AssignableRoleConditionResult fromFail(AssignableRoleConditionType cause, AssignableRolePlaceConditionModel model) {
return AssignableRoleConditionResult
.builder()
.causingCondition(cause)
.model(model)
.fulfilled(false)
.build();
}
public static AssignableRoleConditionResult fromFail(AssignableRoleConditionType cause) {
return AssignableRoleConditionResult
.builder()
.causingCondition(cause)
.fulfilled(false)
.build();
}
public static AssignableRoleConditionResult fromSuccess() {
return AssignableRoleConditionResult
.builder()
.fulfilled(true)
.build();
}
}

View File

@@ -0,0 +1,7 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
public enum AssignableRoleConditionType implements CommandParameterKey {
MIN_LEVEL
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleMinLevelModel {
private Integer minLevel;
private RoleDisplay roleDisplay;
}

View File

@@ -0,0 +1,22 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleMinLevelResult implements AssignableRolePlaceConditionModel {
private AssignableRoleMinLevelModel model;
@Override
public String getTemplateName() {
return "assignable_role_condition_min_level";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -0,0 +1,6 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface AssignableRolePlaceConditionModel extends Templatable {
}

View File

@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import lombok.*;
import javax.persistence.*;
@@ -33,12 +34,8 @@ public class AssignableRole implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* The {@link AEmote emote} this role is associated with
*/
@OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "emote_id", nullable = false)
private AEmote emote;
@Column(name = "emote_markdown")
private String emoteMarkdown;
/**
* The {@link ARole} which given via this {@link AssignableRole assignableRole}
@@ -61,14 +58,6 @@ public class AssignableRole implements Serializable {
@JoinColumn(name = "assignable_place_id", nullable = false)
private AssignableRolePlace assignablePlace;
/**
* The {@link AssignableRolePlacePost} this assignable role is currently available as a reaction.
* This is necessary, to easier find the reaction which are valid, in case a reaction is added to a post
*/
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "place_post_id")
private AssignableRolePlacePost assignableRolePlacePost;
/**
* The {@link AssignedRoleUser users} which currently have this role assigned via this mechanism.
* This is necessary to enforce the unique property of {@link AssignableRolePlace}, in which you only may chose one
@@ -79,23 +68,14 @@ public class AssignableRole implements Serializable {
private List<AssignedRoleUser> assignedUsers = new ArrayList<>();
/**
* The description which is shown in the embeds of the posts of the {@link AssignableRolePlace}
* The display text which is used for the button
*/
@Column(name = "description", nullable = false)
private String description;
/**
* The level in experience which is required in order to receive this {@link AssignableRole}
*/
@Column(name = "required_level")
private Integer requiredLevel;
/**
* The position of this assignable role within the {@link AssignableRole}. This is required in order to show them
* the same order as the descriptions in the fields and also to move them around and switch positions
*/
@Column(name = "position", nullable = false)
private Integer position;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "component_id", nullable = false)
private ComponentPayload componentPayload;
/**
* The {@link Instant} this entity was created
@@ -108,4 +88,13 @@ public class AssignableRole implements Serializable {
*/
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true,
mappedBy = "assignableRole"
)
@Builder.Default
private List<AssignableRoleCondition> conditions = new ArrayList<>();
}

View File

@@ -0,0 +1,34 @@
package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import lombok.*;
import javax.persistence.*;
@Entity
@Table(name = "assignable_role_condition")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AssignableRoleCondition {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Getter
@Enumerated(EnumType.STRING)
@Column(name = "type")
private AssignableRoleConditionType type;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "assignable_role_id", nullable = false)
private AssignableRole assignableRole;
@Column(name = "condition_value")
private String conditionValue;
}

View File

@@ -36,9 +36,6 @@ public class AssignableRolePlace implements Serializable {
@Column(name = "id", nullable = false)
private Long id;
/**
* The channel in which the {@link AssignableRolePlacePost posts} for this place should be created
*/
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="channel_id", nullable = false)
private AChannel channel;
@@ -56,19 +53,6 @@ public class AssignableRolePlace implements Serializable {
@Column(name = "key", nullable = false)
private String key;
/**
* The {@link AssignableRolePlacePost posts} which were created when this place was setup. Is empty in the beginning
* and actively maintained in case a post is deleted.
*/
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true,
mappedBy = "assignablePlace"
)
@Builder.Default
private List<AssignableRolePlacePost> messagePosts = new ArrayList<>();
/**
* A List containing the {@link AssignableRole} which are associated with this place
*/
@@ -81,26 +65,12 @@ public class AssignableRolePlace implements Serializable {
@Builder.Default
private List<AssignableRole> assignableRoles = new ArrayList<>();
/**
* The text which is displayed in the first description area of the created {@link AssignableRolePlacePost}
*/
@Column(name = "message_id")
private Long messageId;
@Column(name = "text", nullable = false)
private String text;
/**
* Whether or not the reactions placed onto the posts should be acted upon
*/
@Builder.Default
@Column(name = "active", nullable = false)
private Boolean active = true;
/**
* Whether or not the fields containing the descriptions should be inline
*/
@Builder.Default
@Column(name = "inline", nullable = false)
private Boolean inline = false;
/**
* Whether or not it should be restricted, that a {@link AssignedRoleUser} should only have one role of this place
*/
@@ -108,13 +78,6 @@ public class AssignableRolePlace implements Serializable {
@Column(name = "unique_roles", nullable = false)
private Boolean uniqueRoles = false;
/**
* Whether or not the added reactions should be removed automatically
*/
@Builder.Default
@Column(name = "auto_remove", nullable = false)
private Boolean autoRemove = false;
/**
* The {@link Instant} this entity was created
*/

View File

@@ -1,78 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
/**
* One individual {@link net.dv8tion.jda.api.entities.Message message} which was sent when setting up an {@link AssignableRolePlace place}
* and contains the embeds and the reactions were placed onto it.
*/
@Entity
@Table(name = "assignable_role_place_post")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AssignableRolePlacePost implements Serializable {
/**
* The ID of the {@link net.dv8tion.jda.api.entities.Message message} which represents this post with the reactions.
*/
@Id
@Column(name = "id", nullable = false)
private Long id;
/**
* The actual {@link AChannel channel} in which the post ended up in
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "channel_id", nullable = false)
private AChannel usedChannel;
/**
* The {@link AServer server} in which this place post is posted
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
/**
* The {@link AssignableRolePlace place} this post is associated with
*/
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "assignable_place_id", nullable = false)
private AssignableRolePlace assignablePlace;
/**
* The actual {@link AssignableRole assignableRoles} which are associated with this post, and whose respective {@link dev.sheldan.abstracto.core.models.database.AEmote}
* have been placed as reactions
*/
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
mappedBy = "assignableRolePlacePost")
@Builder.Default
private List<AssignableRole> assignableRoles = new ArrayList<>();
/**
* The {@link Instant} this entity was created
*/
@Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created;
/**
* The {@link Instant} this entity was updated
*/
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import lombok.Builder;
import lombok.Getter;
@@ -12,13 +12,6 @@ import java.io.Serializable;
@Getter
@Builder
public class AssignableRoleAlreadyDefinedExceptionModel implements Serializable {
/**
* The {@link FullEmote emote} which was tried to be added to a {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
private final FullEmote emote;
/**
* The key of the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace} for which it was tried to add a
* {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private final RoleDisplay roleDisplay;
private final String placeName;
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@Builder
public class AssignableRoleNotFoundExceptionModel implements Serializable {
private Long roleId;
private String displayText;
}

View File

@@ -1,9 +1,8 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import dev.sheldan.abstracto.core.models.FullRole;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import lombok.Builder;
import lombok.Getter;
import net.dv8tion.jda.api.entities.Guild;
import java.io.Serializable;
@@ -13,12 +12,5 @@ import java.io.Serializable;
@Getter
@Builder
public class AssignableRoleNotUsableExceptionModel implements Serializable {
/**
* The {@link FullRole role} which is not usable as an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private final FullRole role;
/**
* The {@link Guild server} in which it was not possible to use the {@link net.dv8tion.jda.api.entities.Role role}
*/
private final transient Guild guild;
private final RoleDisplay roleDisplay;
}

View File

@@ -1,18 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import lombok.Builder;
import lombok.Getter;
import java.io.Serializable;
/**
* Contains the model for {@link dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlaceNotFoundException}
*/
@Getter
@Builder
public class AssignableRolePlaceNotFoundExceptionModel implements Serializable {
/**
* The ID of the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place} which was not found
*/
private final Long placeId;
}

View File

@@ -1,18 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import lombok.Builder;
import lombok.Getter;
import java.io.Serializable;
/**
* Contains the model for {@link dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlacePostNotFoundException}
*/
@Getter
@Builder
public class AssignableRolePlacePostNotFoundExceptionModel implements Serializable {
/**
* The ID of the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost post} which was not found in the database
*/
private final Long messageId;
}

View File

@@ -1,6 +1,5 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import lombok.Builder;
import lombok.Getter;
@@ -12,8 +11,5 @@ import java.io.Serializable;
@Getter
@Builder
public class AssignedUserNotFoundExceptionModel implements Serializable {
/**
* The instance of the {@link AUserInAServer userInAServer} for which the assigned user was not found
*/
private final AUserInAServer aUserInAServer;
private final Long userId;
}

View File

@@ -1,23 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.exception;
import dev.sheldan.abstracto.core.models.FullEmote;
import lombok.Builder;
import lombok.Getter;
import java.io.Serializable;
/**
* Contains the model for {@link dev.sheldan.abstracto.assignableroles.exception.EmoteNotInAssignableRolePlaceException}
*/
@Getter
@Builder
public class EmoteNotInAssignableRolePlaceExceptionModel implements Serializable {
/**
* The {@link FullEmote emote} which was not found in the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
private final FullEmote emote;
/**
* The key of the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place} for which the emote was not found in
*/
private final String placeName;
}

View File

@@ -19,5 +19,5 @@ public class AssignablePlaceOverview {
* The {@link AssignableRolePlace places} in the server to display
*/
@Builder.Default
private List<AssignableRolePlace> places = new ArrayList<>();
private List<AssignableRolePlaceConfig> places = new ArrayList<>();
}

View File

@@ -5,7 +5,9 @@ import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Model used to render the {@link AssignableRolePlace place}
@@ -14,10 +16,8 @@ import java.util.List;
@Setter
@Builder
public class AssignablePostMessage {
/**
* The {@link AssignableRolePlace place} to render
*/
private AssignableRolePlace place;
private Long placeId;
private String placeDescription;
/**
* The awarded {@link AssignablePostRole roles} for this {@link AssignableRolePlace place}
*/
@@ -27,4 +27,6 @@ public class AssignablePostMessage {
* {@link AssignableRolePlace place}
*/
private Integer maxPosition;
@Builder.Default
private Map<String, Long> componentIdToRole = new HashMap<>();
}

View File

@@ -1,40 +1,14 @@
package dev.sheldan.abstracto.assignableroles.model.template;
import dev.sheldan.abstracto.core.models.FullEmote;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
/**
* The model which is used to render the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlacePost post}
* to a {@link dev.sheldan.abstracto.core.templating.model.MessageToSend messageToSend} for one individual {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
@Getter
@Setter
@Builder
public class AssignablePostRole {
/**
* The {@link FullEmote emote} to be used in the field
*/
private FullEmote emote;
/**
* The description to be used in the field
*/
private String emoteMarkDown;
private String description;
/**
* The relative position within the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place} of this
* {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private Integer position;
/**
* Whether or not this field should be at the beginning of a new {@link net.dv8tion.jda.api.entities.Message message}
* to be send
*/
@Builder.Default
private Boolean forceNewMessage = false;
/**
* Whether or not the field should be displayed inline
*/
private Boolean inline;
private String componentId;
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.assignableroles.model.template;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.core.models.template.display.ChannelDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@@ -14,10 +15,10 @@ import java.util.List;
@Setter
@Builder
public class AssignableRolePlaceConfig {
/**
* The {@link AssignableRolePlace place} to show the config of
*/
private AssignableRolePlace place;
private String placeName;
private String placeText;
private ChannelDisplay channelDisplay;
private Boolean uniqueRoles;
/**
* The {@link AssignableRolePlaceConfig roles} which are contained in this {@link AssignableRolePlace}
*/

View File

@@ -1,11 +1,13 @@
package dev.sheldan.abstracto.assignableroles.model.template;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Role;
import java.util.List;
/**
* Model used to display the configuration of an individual {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole}
@@ -15,24 +17,8 @@ import net.dv8tion.jda.api.entities.Role;
@Setter
@Builder
public class AssignableRolePlaceConfigRole {
/**
* The description used for the field for this {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private String description;
/**
* The position of this {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private Integer position;
/**
* Whether or not the field is displayed inline
*/
private Boolean inline;
/**
* The {@link FullEmote emote} which is associated with this {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
*/
private FullEmote emote;
/**
* The {@link dev.sheldan.abstracto.core.models.database.ARole} which is given/removed upon reacting with the emote
*/
private Role awardedRole;
private String emoteMarkDown;
private RoleDisplay roleDisplay;
private List<AssignableRoleConditionDisplay> conditions;
}

View File

@@ -0,0 +1,17 @@
package dev.sheldan.abstracto.assignableroles.model.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Role;
import java.util.List;
@Getter
@Setter
@Builder
public class AssignableRoleSuccessNotificationModel {
private Role role;
private Boolean added;
private List<Role> removedRoles;
}

View File

@@ -0,0 +1,8 @@
package dev.sheldan.abstracto.assignableroles.model.template.condition;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface AssignableRoleConditionDisplay extends Templatable {
}

View File

@@ -0,0 +1,24 @@
package dev.sheldan.abstracto.assignableroles.model.template.condition;
public class AssignableRoleMinLevelDisplay implements AssignableRoleConditionDisplay {
private final AssignableRoleMinLevelDisplayModel model;
public AssignableRoleMinLevelDisplay(Integer level) {
this.model = AssignableRoleMinLevelDisplayModel
.builder()
.minLevel(level)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_condition_display_min_level";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -0,0 +1,12 @@
package dev.sheldan.abstracto.assignableroles.model.template.condition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleMinLevelDisplayModel {
private Integer minLevel;
}

View File

@@ -0,0 +1,19 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import java.util.List;
public interface AssignableRoleConditionService {
AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, Member member, Role role);
AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, AUserInAServer aUserInAServer, Role role);
AssignableRoleCondition createAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type, String value);
void deleteAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type);
List<AssignableRoleConditionDisplay> getConditionDisplays(List<AssignableRoleCondition> conditions);
}

View File

@@ -1,431 +1,56 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey;
import dev.sheldan.abstracto.assignableroles.exception.EmoteNotInAssignableRolePlaceException;
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.core.command.exception.AbstractoTemplatedException;
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageReaction;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.TextChannel;
import java.util.concurrent.CompletableFuture;
/**
* Service responsible to manage actions on an {@link AssignableRolePlace assignableRolePlace}
*/
public interface AssignableRolePlaceService {
/**
* Creates a {@link AssignableRolePlace place} with the given parameters
* @param name The key of the {@link AssignableRolePlace} to be used
* @param channel The {@link AChannel channel} in which the posts of this {@link AssignableRolePlace place} should be posted, also determines
* the {@link AServer server} in which the place should reside in. This {@link AServer server} needs to be unique in combination with the
* key
* @param text The description of the {@link AssignableRolePlace place} which is displayed in the first post of the place
* @throws dev.sheldan.abstracto.assignableroles.exception.AssignableRoleAlreadyDefinedException if the combination of {@link AServer server}
* and {@link AssignableRolePlace#key} already exists
*/
void createAssignableRolePlace(String name, AChannel channel, String text);
/**
* Whether or not the {@link AssignableRolePlace place} already has the given {@link AEmote emote} as an {@link AssignableRole role}
* with the given {@link AEmote emote}
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} should be in
* @param placeName The key of an {@link AssignableRolePlace place} to check
* @param emote The {@link AEmote emote} which is sought after
* @return Whether or not the {@link AssignableRolePlace place} already has an {@link AssignableRole role}
* with the associated {@link AEmote emote}
*/
boolean hasAssignableRolePlaceEmote(AServer server, String placeName, AEmote emote);
CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote emote, String description);
/**
* Whether or not the {@link AssignableRolePlace place} (identified by {@link AServer server} and placeName) already has
* the given {@link AEmote emote} as an {@link AssignableRole role}
* with the given {@link AEmote emote}
* @param place The {@link AssignableRolePlace place} in which the {@link AEmote emote} should be sought in
* @param emote The {@link AEmote emote} which is sought after
* @return Whether or not the {@link AssignableRolePlace place} already has an {@link AssignableRole role}
* with the associated {@link AEmote emote}
*/
boolean hasAssignableRolePlaceEmote(AssignableRolePlace place, AEmote emote);
CompletableFuture<Void> removeRoleFromAssignableRolePlace(AServer server, String placeName, ARole role);
/**
* Whether or not the {@link AssignableRolePlace place} has the position used. Each of the {@link AssignableRole roles}
* in the {@link AssignableRolePlace place} has a position in which it is posted. This is used to order the roles when posting them. This position is an {@link Integer integer}
* and it is not guaranteed every position up until the amount of {@link AssignableRole roles} is used.
* There can be spots, it is only used as an ordering and to swap/move {@link AssignableRole roles}
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} should be in
* @param placeName The key of the {@link AssignableRolePlace place}
* @param position The position of an {@link AssignableRole role} within the place
* @return Whether or not there exists an {@link AssignableRole role} within the
* {@link AssignableRolePlace place} identified by the {@link AServer server} and key
*/
boolean isPositionUsed(AServer server, String placeName, Integer position);
/**
* Sets the {@link AssignableRole role} identified by the
* {@link FullEmote emote} to the given {@link Integer position} in the {@link AssignableRolePlace place} identified by the
* {@link AServer server} and key.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} should be
* @param placeName The key of the {@link AssignableRolePlace place}
* @param emote The {@link FullEmote emote} which identifies the {@link AssignableRole role}
* which position should be changed
* @param position The new position of the {@link AssignableRole role}
* within the place
* @throws AbstractoTemplatedException if the position is already used or the {@link FullEmote emote} has not associated {@link AssignableRole role}
* within the place
*/
void setEmoteToPosition(AServer server, String placeName, FullEmote emote, Integer position);
/**
* Adds the given {@link ARole role} to the {@link AssignableRolePlace place} identified by the {@link AServer server} and key
* in the form as a {@link AssignableRole role}. This role is identified
* by the given {@link FullEmote emote} and has the description. If the {@link AssignableRolePlace place} is already setup, this will
* try to update the message: adding the field and the reaction. This might not always work e.g. the reaction limit was reached.
* If the update is successful, it will also store the updates in the database.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is present
* @param placeName The key of the {@link AssignableRolePlace place}
* @param role The {@link ARole role} which should be awarded when reacting with the given {@link FullEmote emote}
* @param emote The {@link FullEmote emote} which should be placed on the {@link Message message}
* to react to and identify the {@link AssignableRole}
* for this place
* @param description The description which will be displayed in the {@link Message message}
* which has the reactions
* @throws dev.sheldan.abstracto.core.exception.EmoteNotUsableException in case the {@link net.dv8tion.jda.api.entities.Emote emote}
* cannot be used by the current user. This might be an issue, if its from an external {@link net.dv8tion.jda.api.entities.Guild}
* the user is not a part of.
* @return A {@link CompletableFuture future} when the {@link Message message} has been updated
* and the {@link MessageReaction reaction} has been added. Only tries to execute this, in case there
* {@link AssignableRolePlacePost posts} known.
*/
CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, ARole role, FullEmote emote, String description);
/**
* Removes the given {@link AssignableRole role} from the {@link AssignableRolePlace place}
* identified by the {@link AServer server} and the key. The {@link AssignableRole role} is identified
* by the {@link FullEmote emote} which is associated to it. If there are already {@link AssignableRolePlacePost posts}
* for this {@link AssignableRolePlace place} this will remove the {@link MessageReaction reaction} and
* edit the {@link Message message}. If not, the method returns immediately. If the update
* was successful or was not necessary, the data will be updated in the database as well.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param placeName The key of the {@link AssignableRolePlace place} to remove an {@link AssignableRole role}
* from
* @param emote The {@link FullEmote fullEmote} which has an {@link AEmote emote} to identify the {@link AssignableRole role}
* to remove
* @return A {@link CompletableFuture future} which completes when the {@link MessageReaction reaction}
* was removed and the {@link Message message} updated and the database updated, or, if no post is present, only if the database was updated
*/
CompletableFuture<Void> removeRoleFromAssignableRolePlace(AServer server, String placeName, FullEmote emote);
/**
* This method is used to setup the {@link AssignableRolePlacePost} for an
* {@link AssignableRolePlace place}. If there are previous {@link AssignableRolePlacePost posts},
* this method will delete them first. This method does not do the rendering, but is only the entry point for the process.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key which identifies the {@link AssignableRolePlace place} within the {@link AServer server}
* @return A {@link CompletableFuture future} which completes if the complete setup is finished successfully.
*/
CompletableFuture<Void> setupAssignableRolePlace(AServer server, String name);
/**
* This method is used to update the {@link AssignableRolePlacePost posts}
* of the {@link AssignableRolePlace place} identified by the {@link AServer server} and the key. This
* effectively re-renders the template for an {@link AssignableRolePlace place} and updates the existing
* {@link AssignableRolePlacePost posts} accordingly. In case there are no posts, this method returns immediately.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @throws ChannelNotInGuildException if the channel which contained the posts does not exist anymore
* @return A {@link CompletableFuture future} which completes successfully if *every* update was successful.
*/
CompletableFuture<Void> refreshAssignablePlacePosts(AServer server, String name);
/**
* This method is used to update the {@link AssignableRolePlacePost posts}
* of the {@link AssignableRolePlace place}. This effectively re-renders the template for an
* {@link AssignableRolePlace place} and updates the existing {@link AssignableRolePlacePost posts} accordingly.
* In case there are no posts, this method returns immediately.
* @param place The {@link AssignableRolePlace place} which should have their {@link Message messages} were updated
* @throws ChannelNotInGuildException if the channel which contained the posts does not exist anymore
* @return A {@link CompletableFuture future} which completes successfully if *every* update was successful.
*/
CompletableFuture<Void> refreshAssignablePlacePosts(AssignableRolePlace place);
/**
* This method updates the first {@link AssignableRolePlacePost posts} which contains the description of the
* {@link AssignableRolePlace place}. If there are no posts, this method will return immediately
* @param place The {@link AssignableRolePlace place} to update the
* @throws ChannelNotInGuildException if the channel which contained the post does not exist anymore
* @return A {@link CompletableFuture future} which completes when the update of the {@link Message message}
* was completed
*/
CompletableFuture<Void> refreshTextFromPlace(AssignableRolePlace place);
/**
* Sets the active attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newValue The new vale of the active attribute
*/
void setAssignablePlaceActiveTo(AServer server, String name, Boolean newValue);
CompletableFuture<Void> setAssignablePlaceActiveTo(AServer server, String name, Boolean newValue);
/**
* Activates the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to activate
*/
void activateAssignableRolePlace(AServer server, String name);
CompletableFuture<Void> activateAssignableRolePlace(AServer server, String name);
/**
* Activates the {@link AssignableRolePlace place}, which means that the activate attribute will be set to true
* @param place The {@link AssignableRolePlace place} to activate
*/
void activateAssignableRolePlace(AssignableRolePlace place);
CompletableFuture<Void> activateAssignableRolePlace(AssignableRolePlace place);
/**
* De-activates the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to de-activate
*/
void deactivateAssignableRolePlace(AServer server, String name);
CompletableFuture<Void> deactivateAssignableRolePlace(AServer server, String name);
/**
* De-activates the {@link AssignableRolePlace place}, which means that the activate attribute will be set to false
* @param place The {@link AssignableRolePlace place} to de-activate
*/
void deactivateAssignableRolePlace(AssignableRolePlace place);
CompletableFuture<Void> deactivateAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the inline attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key. This method will update any existing {@link AssignableRolePlacePost posts} of the place, if there
* are any.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newValue The new vale of the inline attribute
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> setAssignablePlaceInlineTo(AServer server, String name, Boolean newValue);
/**
* Sets the inline attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to true. This method will update any existing {@link AssignableRolePlacePost posts} of the place, if there
* are any.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to inline
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> inlineAssignableRolePlace(AServer server, String name);
/**
* Sets the inline attribute of the {@link AssignableRolePlace place} to true. This method will update any existing
* {@link AssignableRolePlacePost posts} of the place, if there are any.
* @param place The {@link AssignableRolePlace place} to inline
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> inlineAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the inline attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to false. This method will update any existing {@link AssignableRolePlacePost posts} of the place, if there
* are any.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to spread
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> spreadAssignableRolePlace(AServer server, String name);
/**
* Sets the inline attribute of the {@link AssignableRolePlace place} to false. This method will update any existing
* {@link AssignableRolePlacePost posts} of the place, if there are any.
* @param place The {@link AssignableRolePlace place} to spread
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> spreadAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the unique attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newValue The new vale of the unique attribute
*/
void setAssignablePlaceUniqueTo(AServer server, String name, Boolean newValue);
/**
* Sets the unique attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to true.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to activate unique role handling
*/
void uniqueAssignableRolePlace(AServer server, String name);
/**
* Sets the unique attribute of the {@link AssignableRolePlace place} to true.
* @param place The {@link AssignableRolePlace place} to activate unique role handling
*/
void uniqueAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the unique attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to false.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to disable unique role handling
*/
void multipleAssignableRolePlace(AServer server, String name);
/**
* Sets the unique attribute of the {@link AssignableRolePlace place} to false.
* @param place The {@link AssignableRolePlace place} to disable unique role handling
*/
void multipleAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the auto-remove attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newValue The new vale of the auto-remove attribute
*/
void setAssignablePlaceAutoRemoveTo(AServer server, String name, Boolean newValue);
/**
* Sets the auto-remove attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to true.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to activate the automatic removal of reactions
*/
void autoRemoveAssignableRolePlace(AServer server, String name);
/**
* Sets the auto-remove attribute of the {@link AssignableRolePlace place} to true.
* @param place The {@link AssignableRolePlace place} to activate the automatic removal of reactions
*/
void autoRemoveAssignableRolePlace(AssignableRolePlace place);
/**
* Sets the auto-remove attribute of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and the key to false.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place} to keep reactions
*/
void keepReactionsAssignableRolePlace(AServer server, String name);
/**
* Sets the auto-remove attribute of the {@link AssignableRolePlace place} to false.
* @param place The {@link AssignableRolePlace place} to keep reactions
*/
void keepReactionsAssignableRolePlace(AssignableRolePlace place);
/**
* Swaps the positions of the two {@link AssignableRole roles} identified by the respective
* {@link FullEmote emote}. This will only update the it in the database, and require a new setup. The
* two {@link FullEmote emotes} are assumed to be different
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param firstEmote The {@link FullEmote emote} which identifies the first {@link AssignableRole role} to swap
* @param secondEmote The {@link FullEmote emote} which identifies the second {@link AssignableRole role} to swap
* @throws EmoteNotInAssignableRolePlaceException if either one of them is not part of the {@link AssignableRolePlace place}
*
*/
void swapPositions(AServer server, String name, FullEmote firstEmote, FullEmote secondEmote);
/**
* This method renders the {@link AssignableRolePlace place} and post the created {@link MessageToSend messageToSend}
* in the current channel.
* @param server The {@link AServer server} of the {@link AssignableRolePlace place} to test
* @param name The key of the {@link AssignableRolePlace place}
* @param channel The {@link TextChannel channel} in which the resulting {@link MessageToSend messageToSend}
* should be posted in
* @return A {@link CompletableFuture future} which completes when all {@link MessageToSend messageToSend}
* have been sent
*/
CompletableFuture<Void> testAssignableRolePlace(AServer server, String name, TextChannel channel);
/**
* This method renders the configuration of the {@link AssignableRolePlace place} identified by {@link AServer server}
* and key into an {@link MessageToSend messageToSend} and sends a message to the given {@link TextChannel channel}.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param channel The {@link TextChannel channel} in which the resulting {@link MessageToSend messageToSend} should be posted in
* @return A {@link CompletableFuture future} which completes when the {@link MessageToSend} has been sent
*/
CompletableFuture<Void> showAssignablePlaceConfig(AServer server, String name, TextChannel channel);
/**
* Changes the {@link AChannel channel} of the {@link AssignableRole place} identified by {@link AServer server}
* and key to the given {@link TextChannel channel}. This only changes the configuration and does not impact
* any currently posted {@link AssignableRolePlacePost posts}
* @param name The key of the {@link AssignableRolePlace place}
* @param newChannel The {@link TextChannel channel} where the {@link AssignableRolePlace place} should be posted to.
*/
void moveAssignableRolePlace(String name, TextChannel newChannel);
CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel);
/**
* Deletes the {@link AssignableRolePlace place} identified by {@link AServer server} and key. This method will first
* delete all the {@link AssignableRolePlacePost posts} and then remove the references from the database.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @return A {@link CompletableFuture future} which completes after all posts have been deleted
*/
CompletableFuture<Void> deleteAssignableRolePlace(AServer server, String name);
/**
* Changes the text of an {@link AssignableRolePlace place} in the database only.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newText The new value for the text attribute displayed in the first {@link AssignableRolePlacePost post}
*/
void changeText(AServer server, String name, String newText);
/**
* Changes the text of an {@link AssignableRolePlace place} in the database, and updates the first
* {@link AssignableRolePlacePost post}. The update of the post happens after the change in the database.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param newText The new value for the text attribute displayed in the first {@link AssignableRolePlacePost post}
* @return A {@link CompletableFuture future} which completes when the config has been updated, or when the message was edited (if the posts already exist)
*/
CompletableFuture<Void> changeTextAsync(AServer server, String name, String newText);
/**
* Removes the reactions and the roles from the user from the place, this does not touch the stored data
* @param place The {@link AssignableRolePlace place} to which remove the existing reactions and roles from
* @param user The {@link AssignedRoleUser user} to the remove *all* reactions and assigned roles from
* @return A {@link CompletableFuture future} which completes when both of these actions have been done for all {@link AssignableRole assignableRoles}
*/
CompletableFuture<Void> removeExistingReactionsAndRoles(AssignableRolePlace place, AssignedRoleUser user);
CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, String newValue);
/**
* Changes the configuration of the given {@link AssignableRolePlaceParameterKey key} to the given value of the
* {@link AssignableRolePlace place} identified by {@link AServer server} and key. If it can be updated immediately,
* this will update the {@link AssignableRolePlacePost posts} and the return {@link CompletableFuture future}
* will return afterwards. This is the case for {@link AssignableRolePlaceParameterKey#INLINE}. The rest of the
* keys will only update the configuration in the database, and the place needs a refresh at a later point.
* @param server The {@link AServer server} in which the {@link AssignableRolePlace place} is
* @param name The key of the {@link AssignableRolePlace place}
* @param keyToChange The {@link AssignableRolePlaceParameterKey key} to change
* @param newValue The new value of the attribute, but be able to convert to a boolean via {@link org.apache.commons.lang3.BooleanUtils#toBooleanObject(String)}
* @return A {@link CompletableFuture future} which completes when the configuration has been completed
*/
CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, Object newValue);
/**
* Retrieves all {@link AssignableRolePlace places}, renders them into {@link MessageToSend messageToSend} and sends
* this message to the given {@link TextChannel channel}.
* @param server The {@link AServer server} for which the {@link AssignableRolePlace places} should be shown for
* @param channel The {@link TextChannel channel} to send the {@link MessageToSend messageToSend} in
* @return A {@link CompletableFuture future} which completes when the message has been sent
*/
CompletableFuture<Void> showAllAssignableRolePlaces(AServer server, TextChannel channel);
}

View File

@@ -2,9 +2,10 @@ package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import java.util.concurrent.CompletableFuture;
@@ -21,13 +22,6 @@ public interface AssignableRoleService {
*/
CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, Member member);
/**
* Adds the given {@link AssignableRole assignableRole} to the given {@link ServerUser serverUser}
* @param assignableRoleId The ID of the {@link AssignableRole} to add
* @param serverUser The {@link ServerUser serverUser} who should receive the {@link AssignableRole role}
* @return A {@link CompletableFuture future} which completes when the {@link net.dv8tion.jda.api.entities.Role role} was added to the {@link ServerUser serverUser}
*/
CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, ServerUser serverUser);
/**
* Clears all {@link AssignableRole assignableRoles} which are currently given to the {@link AUserInAServer user} of a certain
@@ -37,16 +31,6 @@ public interface AssignableRoleService {
*/
void clearAllRolesOfUserInPlace(AssignableRolePlace place, AUserInAServer user);
/**
* Assigns the given {@link AssignableRole role} to the {@link Member member} and stores the assignment as a
* {@link dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser}
* @param assignableRoleId The ID of an {@link AssignableRole assignableRole} to be added to the {@link Member member}
* @param toAdd The {@link Member member} to add the role to
* @return A {@link CompletableFuture future} which completes when the {@link net.dv8tion.jda.api.entities.Role role} has
* been added and the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser user} has been persisted
*/
CompletableFuture<Void> fullyAssignAssignableRoleToUser(Long assignableRoleId, Member toAdd);
/**
* Removes the {@link AssignableRole role} from the given {@link Member member}
* @param assignableRole The {@link AssignableRole role} to remove
@@ -65,32 +49,6 @@ public interface AssignableRoleService {
*/
CompletableFuture<Void> removeAssignableRoleFromUser(Long assignableRoleId, Member member);
/**
* Removes the {@link AssignableRole role} from the given {@link AUserInAServer aUserInAServer}
* @param assignableRole The {@link AssignableRole role} to remove
* @param aUserInAServer The {@link AUserInAServer aUserInAServer} to remove the {@link AssignableRole role} from
* @return A {@link CompletableFuture future} which completes when the {@link net.dv8tion.jda.api.entities.Role role}
* has been removed from the {@link AUserInAServer aUserInAServer}
*/
CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer);
/**
* Removes the given {@link AssignableRole role} from the {@link ServerUser serverUser} and stores the assignment as a
* {@link dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser}
* @param assignableRole The {@link AssignableRole assignableRole} to be removed from the {@link ServerUser serverUser}
* @param serverUser The {@link ServerUser serverUser} to remove the role from
* @return A {@link CompletableFuture future} which completes when the {@link net.dv8tion.jda.api.entities.Role role} has
* been removed and the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser user} has been persisted
*/
CompletableFuture<Void> fullyRemoveAssignableRoleFromUser(AssignableRole assignableRole, ServerUser serverUser);
/**
* Adds the {@link AssignableRole assignableRole} to the given {@link AUserInAServer userInAServer} in the database
* @param assignableRoleId The ID of the {@link AssignableRole role} to be added
* @param aUserInAServer The {@link AUserInAServer user} to get the {@link AssignableRole role}
*/
void addRoleToUser(Long assignableRoleId, AUserInAServer aUserInAServer);
/**
* Adds the {@link AssignableRole assignableRole} to the given {@link AUserInAServer userInAServer} in the database
* @param assignableRole The {@link AssignableRole role} to be added
@@ -105,10 +63,8 @@ public interface AssignableRoleService {
*/
void removeRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer);
/**
* Removes the {@link AssignableRole assignableRole} from the given {@link AUserInAServer userInAServer} in the database
* @param assignableRoleId The ID of the {@link AssignableRole role} to be removed
* @param aUserInAServer The {@link AUserInAServer user} to get the {@link AssignableRole role} removed
*/
void removeRoleFromUser(Long assignableRoleId, AUserInAServer aUserInAServer);
AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Role role);
AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, ARole role);
AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Long roleId);
}

View File

@@ -0,0 +1,13 @@
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 java.util.Optional;
public interface AssignableRoleConditionManagementService {
AssignableRoleCondition createAssignableRoleCondition(AssignableRole assignableRole, AssignableRoleConditionType type, String value);
void deleteAssignableRoleCondition(AssignableRoleCondition condition);
Optional<AssignableRoleCondition> findAssignableRoleCondition(AssignableRole role, AssignableRoleConditionType type);
}

View File

@@ -2,11 +2,12 @@ package dev.sheldan.abstracto.assignableroles.service.management;
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.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import net.dv8tion.jda.api.entities.MessageReaction;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import net.dv8tion.jda.api.entities.Role;
/**
* Management service for the table of {@link AssignableRole assignableRoles}
@@ -16,39 +17,12 @@ public interface AssignableRoleManagementService {
* Adds the given {@link ARole role} to the {@link AssignableRolePlace place} to be identified with the given {@link AEmote emote}
* and displayed with the given description. An optional {@link AssignableRolePlacePost post} can be provided, if the
* place has already been setup.
* @param place The {@link AssignableRolePlace place} to add the the {@link ARole role} to
* @param emote The {@link AEmote emote} which is used as an reaction on the {@link AssignableRolePlacePost post}
* @param role The {@link ARole role} which should be given to the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer user} placing a reaction
* @param description The description which should be displayed in the field for the given {@link ARole role}
* @param post If a {@link AssignableRolePlacePost post} already exists, it can be provided to link the newly created {@link AssignableRole directly}
* @return The created instance of the {@link AssignableRole assignableRole} according to the given parameters
*/
AssignableRole addRoleToPlace(AssignableRolePlace place, AEmote emote, ARole role, String description, AssignableRolePlacePost post);
/**
* Adds the {@link ARole role} (identified by its ID) to the {@link AssignableRolePlace place} (identified by its ID),
* which in turn is identified by the given {@link AEmote emote} (identified by its ID) and displayed with the given description.
* An optional {@link AssignableRolePlacePost post} can be provided (identified by the ID of the {@link net.dv8tion.jda.api.entities.Message}), if
* it already exists
* @param placeId The ID of the {@link AssignableRolePlace} to add an {@link AssignableRole assignableRole} to
* @param emoteId The ID of the {@link AEmote emote} which should be used as an reaction on the {@link AssignableRolePlacePost post}
* @param roleId The ID of the {@link ARole role} which should be given to the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer user} placing a reaction
* @param description The description which should be displayed in the field for the given {@link ARole role}
* @param messageId If provided, this message ID will be used to identify the {@link AssignableRolePlacePost post} which already exists
* @return The created instance of the {@link AssignableRole assignableRole} according to the given parameters
*/
AssignableRole addRoleToPlace(Long placeId, Integer emoteId, Long roleId, String description, Long messageId);
/**
* Adds the {@link ARole role} (identified by its ID) to the {@link AssignableRolePlace place} (identified by its ID),
* which in turn is identified by the given {@link AEmote emote} (identified by its ID) and displayed with the given description.
* @param placeId The ID of the {@link AssignableRolePlace} to add an {@link AssignableRole assignableRole} to
* @param emoteId The ID of the {@link AEmote emote} which should be used as an reaction on the {@link AssignableRolePlacePost post}
* @param roleId The ID of the {@link ARole role} which should be given to the {@link dev.sheldan.abstracto.core.models.database.AUserInAServer user} placing a reaction
* @param description The description which should be displayed in the field for the given {@link ARole role}
* @return The created instance of the {@link AssignableRole assignableRole} according to the given parameters
*/
AssignableRole addRoleToPlace(Long placeId, Integer emoteId, Long roleId, String description);
AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload);
/**
* Finds the {@link AssignableRole} given by the ID and returns it if found. Throws an exception otherwise.
@@ -56,6 +30,7 @@ public interface AssignableRoleManagementService {
* @return An instance of {@link AssignableRole assignableRole} if it exists for the given ID
*/
AssignableRole getByAssignableRoleId(Long assignableRoleId);
void deleteAssignableRole(AssignableRole assignableRole);
/**
* Returns the respective {@link AssignableRole assignableRole} for the {@link CachedEmote emote} which is part of the
@@ -64,6 +39,4 @@ public interface AssignableRoleManagementService {
* @param assignableRolePlace The {@link AssignableRolePlace place} from which the {@link AssignableRole role} should be retrieved for
* @return An instance of {@link AssignableRole role} which was in the place and identified by the emote
*/
AssignableRole getRoleForReactionEmote(CachedEmote cachedEmote, AssignableRolePlace assignableRolePlace);
AssignableRole getRoleForReactionEmote(MessageReaction.ReactionEmote cachedEmote, AssignableRolePlace assignableRolePlace);
}

View File

@@ -1,37 +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 java.util.Optional;
/**
* Management service for {@link AssignableRolePlacePost post} table
*/
public interface AssignableRolePlacePostManagementService {
/**
* Finds a {@link AssignableRolePlacePost post} via the ID of the {@link net.dv8tion.jda.api.entities.Message} it was
* posted
* @param messageId The ID of the {@link net.dv8tion.jda.api.entities.Message} in which the
* @return An {@link Optional optional} containing the {@link AssignableRolePlacePost post}, if one was found, empty otherwise
*/
Optional<AssignableRolePlacePost> findByMessageIdOptional(Long messageId);
/**
* Finds a {@link AssignableRolePlacePost post} via the ID of the {@link net.dv8tion.jda.api.entities.Message} it was
* posted
* @param messageId The ID of the {@link net.dv8tion.jda.api.entities.Message} in which the
* @throws AssignableRolePlacePostNotFoundException if it was not found
* @return The {@link AssignableRolePlacePost post} if one existed with this ID
*/
AssignableRolePlacePost findByMessageId(Long messageId);
/**
* Creates an {@link AssignableRolePlacePost post} for the given {@link AssignableRolePlace place} in the given message ID
* @param updatedPlace The {@link AssignableRolePlace place} this post should be part of
* @param messageId The ID of the message in which the post exists
* @return The {@link AssignableRolePlacePost post} which is found in the given {@link AssignableRolePlace place} of the {@link net.dv8tion.jda.api.entities.Message message} ID
*/
AssignableRolePlacePost createAssignableRolePlacePost(AssignableRolePlace updatedPlace, Long messageId);
}