mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-05 17:07:03 +00:00
[AB-325] adding async command conditions - as this is required for some conditions
adding user parameter to immune user condition evaluation
This commit is contained in:
@@ -4,6 +4,16 @@ package dev.sheldan.abstracto.core.command.condition;
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface CommandCondition {
|
||||
ConditionResult shouldExecute(CommandContext commandContext, Command command);
|
||||
default ConditionResult shouldExecute(CommandContext commandContext, Command command) {
|
||||
return ConditionResult.fromSuccess();
|
||||
}
|
||||
default boolean isAsync() {
|
||||
return false;
|
||||
}
|
||||
default CompletableFuture<ConditionResult> shouldExecuteAsync(CommandContext commandContext, Command command) {
|
||||
return CompletableFuture.completedFuture(ConditionResult.fromSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@@ -12,10 +14,16 @@ public class ConditionResult {
|
||||
private String reason;
|
||||
private ConditionDetail conditionDetail;
|
||||
|
||||
public static final ConditionResult SUCCESS = ConditionResult.builder().result(true).build();
|
||||
|
||||
public static ConditionResult fromSuccess() {
|
||||
return ConditionResult.builder().result(true).build();
|
||||
}
|
||||
|
||||
public static CompletableFuture<ConditionResult> fromAsyncSuccess() {
|
||||
return CompletableFuture.completedFuture(fromSuccess());
|
||||
}
|
||||
|
||||
public static ConditionResult fromFailure(ConditionDetail detail) {
|
||||
return ConditionResult.builder().result(false).conditionDetail(detail).build();
|
||||
}
|
||||
|
||||
@@ -7,16 +7,22 @@ import dev.sheldan.abstracto.core.command.config.EffectConfig;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.RoleImmunity;
|
||||
import dev.sheldan.abstracto.core.service.RoleImmunityService;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -34,32 +40,92 @@ public class ImmuneUserCondition implements CommandCondition {
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
@Autowired
|
||||
private ImmuneUserCondition self;
|
||||
|
||||
@Override
|
||||
public ConditionResult shouldExecute(CommandContext context, Command command) {
|
||||
public CompletableFuture<ConditionResult> shouldExecuteAsync(CommandContext commandContext, Command command) {
|
||||
CommandConfiguration commandConfig = command.getConfiguration();
|
||||
if(commandConfig.getEffects().isEmpty()) {
|
||||
return ConditionResult.fromSuccess();
|
||||
return ConditionResult.fromAsyncSuccess();
|
||||
}
|
||||
List<Object> parameters = context.getParameters().getParameters();
|
||||
List<CompletableFuture<Member>> futures = new ArrayList<>();
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
for (EffectConfig effectConfig : commandConfig.getEffects()) {
|
||||
Integer position = effectConfig.getPosition();
|
||||
if (position < parameters.size()) {
|
||||
Object parameter = parameters.get(position);
|
||||
if (parameter instanceof Member) {
|
||||
Member member = (Member) parameter;
|
||||
Optional<RoleImmunity> immunityOptional = roleImmunityService.getRoleImmunity(member, effectConfig.getEffectKey());
|
||||
if (immunityOptional.isPresent()) {
|
||||
RoleImmunity immunity = immunityOptional.get();
|
||||
ImmuneUserConditionDetail conditionDetail = new ImmuneUserConditionDetail(roleService.getRoleFromGuild(immunity.getRole()),
|
||||
effectConfig.getEffectKey());
|
||||
return ConditionResult.fromFailure(conditionDetail);
|
||||
}
|
||||
futures.add(CompletableFuture.completedFuture(member));
|
||||
} else if (parameter instanceof User) {
|
||||
User user = (User) parameter;
|
||||
futures.add(commandContext.getGuild().retrieveMember(user).submit());
|
||||
}
|
||||
} else {
|
||||
log.info("Not enough parameters ({}) in command {} to retrieve position {} to check for immunity.",
|
||||
parameters.size(), commandConfig.getName(), position);
|
||||
}
|
||||
}
|
||||
return ConditionResult.fromSuccess();
|
||||
if(!futures.isEmpty()) {
|
||||
CompletableFuture<ConditionResult> resultFuture = new CompletableFuture<>();
|
||||
CompletableFutureList<Member> futureList = new CompletableFutureList<>(futures);
|
||||
futureList.getMainFuture().whenComplete((unused, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Future for user immune condition failed. Continuing processing.", throwable);
|
||||
}
|
||||
Map<Long, Member> memberMap = futureList
|
||||
.getObjects()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Member::getIdLong, Function.identity()));
|
||||
self.checkConditions(commandConfig, parameters, resultFuture, memberMap);
|
||||
}).exceptionally(throwable -> {
|
||||
resultFuture.completeExceptionally(throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return resultFuture;
|
||||
} else {
|
||||
return ConditionResult.fromAsyncSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void checkConditions(CommandConfiguration commandConfig, List<Object> parameters, CompletableFuture<ConditionResult> resultFuture, Map<Long, Member> memberMap) {
|
||||
for (EffectConfig effectConfig : commandConfig.getEffects()) {
|
||||
Integer position = effectConfig.getPosition();
|
||||
if (position < parameters.size()) {
|
||||
Object parameter = parameters.get(position);
|
||||
Member member = null;
|
||||
if (parameter instanceof Member) {
|
||||
member = (Member) parameter;
|
||||
} else if (parameter instanceof User) {
|
||||
User user = (User) parameter;
|
||||
member = memberMap.get(user.getIdLong());
|
||||
}
|
||||
if(member != null) {
|
||||
Optional<RoleImmunity> immunityOptional = roleImmunityService.getRoleImmunity(member, effectConfig.getEffectKey());
|
||||
if (immunityOptional.isPresent()) {
|
||||
RoleImmunity immunity = immunityOptional.get();
|
||||
ImmuneUserConditionDetail conditionDetail = new ImmuneUserConditionDetail(roleService.getRoleFromGuild(immunity.getRole()),
|
||||
effectConfig.getEffectKey());
|
||||
resultFuture.complete(ConditionResult.fromFailure(conditionDetail));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
resultFuture.completeExceptionally(new AbstractoRunTimeException("No member found for given member in condition."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
log.info("Not enough parameters ({}) in command {} to retrieve position {} to check for immunity.",
|
||||
parameters.size(), commandConfig.getName(), position);
|
||||
}
|
||||
}
|
||||
resultFuture.complete(ConditionResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public interface CommandService {
|
||||
void unRestrictCommand(ACommand aCommand, AServer server);
|
||||
void disAllowCommandForRole(ACommand aCommand, ARole role);
|
||||
void disAllowFeatureForRole(FeatureDefinition featureDefinition, ARole role);
|
||||
ConditionResult isCommandExecutable(Command command, CommandContext commandContext);
|
||||
CompletableFuture<ConditionResult> isCommandExecutable(Command command, CommandContext commandContext);
|
||||
UnParsedCommandParameter getUnParsedCommandParameter(String messageContent, Message message);
|
||||
CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent);
|
||||
Parameter cloneParameter(Parameter parameter);
|
||||
|
||||
Reference in New Issue
Block a user