mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-21 15:25:50 +00:00
[AB-128] adding command cooldowns on server/channel group and member level
fixing channel group names being made lower case before storing changing channel group deleted to be sync instead refactoring exceptions and adding exception message to a few fixing channel group incorrect type using the wrong template showing more information in list channel groups command allowing commands to be in any channel group adding concept of channel group types not allowing channels/commands to be in multiple of the same type adding structure to retrieve information about channel groups adding ability to disable channel groups changing loading of member parameter handler to not use cache
This commit is contained in:
@@ -3,4 +3,7 @@ package dev.sheldan.abstracto.modmail.exception;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
|
||||
public class ModMailThreadChannelNotFound extends AbstractoRunTimeException {
|
||||
public ModMailThreadChannelNotFound() {
|
||||
super("Modmail thread channel not found.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dev.sheldan.abstracto.repostdetection.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
@@ -11,7 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RepostCheckAsyncChannelGroupDeletedListener implements AsyncChannelGroupDeletedListener {
|
||||
public class RepostCheckChannelGroupDeletedListener implements ChannelGroupDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private RepostCheckChannelGroupManagement checkChannelGroupManagement;
|
||||
@@ -16,10 +16,10 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RepostCheckAsyncChannelGroupDeletedListenerTest {
|
||||
public class RepostCheckChannelGroupDeletedListenerTest {
|
||||
|
||||
@InjectMocks
|
||||
private RepostCheckAsyncChannelGroupDeletedListener testUnit;
|
||||
private RepostCheckChannelGroupDeletedListener testUnit;
|
||||
|
||||
@Mock
|
||||
private RepostCheckChannelGroupManagement checkChannelGroupManagement;
|
||||
@@ -14,6 +14,7 @@ public class TrackedEmoteNotFoundException extends AbstractoRunTimeException imp
|
||||
}
|
||||
|
||||
public TrackedEmoteNotFoundException() {
|
||||
super("Tracked emote not found.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,10 @@ import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class NoUrbanDefinitionFoundException extends AbstractoRunTimeException implements Templatable {
|
||||
public NoUrbanDefinitionFoundException() {
|
||||
super("No urban definition found.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "no_urban_definition_found_exception";
|
||||
|
||||
@@ -9,6 +9,7 @@ public class YoutubeAPIException extends AbstractoRunTimeException implements Te
|
||||
private final YoutubeAPIExceptionModel model;
|
||||
|
||||
public YoutubeAPIException(Throwable throwable) {
|
||||
super("Youtube api exception.");
|
||||
this.model = YoutubeAPIExceptionModel
|
||||
.builder()
|
||||
.exception(throwable)
|
||||
|
||||
@@ -5,6 +5,10 @@ import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class YoutubeVideoNotFoundException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
public YoutubeVideoNotFoundException() {
|
||||
super("No youtube video found.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "webservices_youtube_video_not_found_exception";
|
||||
|
||||
@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.command.execution.UnparsedCommandParameterPiec
|
||||
import dev.sheldan.abstracto.core.command.handler.provided.MemberParameterHandler;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.utils.concurrent.Task;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -38,14 +39,19 @@ public class MemberParameterHandlerImpl implements MemberParameterHandler {
|
||||
long userId = Long.parseLong(inputString);
|
||||
return context.getGuild().retrieveMemberById(userId).submit().thenApply(member -> member);
|
||||
} else {
|
||||
List<Member> possibleMembers = context.getGuild().getMembersByName(inputString, true);
|
||||
if(possibleMembers.isEmpty()) {
|
||||
throw new AbstractoTemplatedException("No member found with name.", "no_member_found_by_name_exception");
|
||||
}
|
||||
if(possibleMembers.size() > 1) {
|
||||
throw new AbstractoTemplatedException("Multiple members found with name.", "multiple_members_found_by_name_exception");
|
||||
}
|
||||
return CompletableFuture.completedFuture(possibleMembers.get(0));
|
||||
Task<List<Member>> listTask = context.getGuild().retrieveMembersByPrefix(inputString, 1);
|
||||
CompletableFuture<Object> memberFuture = new CompletableFuture<>();
|
||||
listTask.onSuccess(members -> {
|
||||
if(members.isEmpty()) {
|
||||
memberFuture.completeExceptionally(new AbstractoTemplatedException("No member found with name.", "no_member_found_by_name_exception"));
|
||||
} else if(members.size() > 1) {
|
||||
memberFuture.completeExceptionally(new AbstractoTemplatedException("Multiple members found with name.", "multiple_members_found_by_name_exception"));
|
||||
} else {
|
||||
memberFuture.complete(members.get(0));
|
||||
}
|
||||
});
|
||||
listTask.onError(memberFuture::completeExceptionally);
|
||||
return memberFuture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.core.command.post;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ResultState;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownService;
|
||||
import dev.sheldan.abstracto.core.command.service.PostCommandExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
public class CoolDownPostExecution implements PostCommandExecution {
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownService commandCoolDownService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void execute(CommandContext commandContext, CommandResult commandResult, Command command) {
|
||||
ResultState result = commandResult.getResult();
|
||||
if(result.equals(ResultState.SUCCESSFUL) || result.equals(ResultState.IGNORED)) {
|
||||
commandCoolDownService.updateCoolDowns(command, commandContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import java.util.Optional;
|
||||
public interface ChannelGroupCommandRepository extends JpaRepository<AChannelGroupCommand, Long> {
|
||||
|
||||
Optional<AChannelGroupCommand> findByCommandAndGroup(ACommand command, AChannelGroup group);
|
||||
List<AChannelGroupCommand> findByCommandAndGroupIn(ACommand command, List<AChannelGroup> groups);
|
||||
|
||||
List<AChannelGroupCommand> findByCommand(ACommand command);
|
||||
List<AChannelGroupCommand> findByCommandAndGroup_ChannelGroupType_GroupTypeKey(ACommand command, String groupType);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.command.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.model.database.CommandDisabledChannelGroup;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CommandDisabledChannelGroupRepository extends JpaRepository<CommandDisabledChannelGroup, Long> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.command.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.model.database.CoolDownChannelGroup;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CoolDownChannelGroupRepository extends JpaRepository<CoolDownChannelGroup, Long> {
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ChannelGroupCommandServiceBean implements ChannelGroupCommandService {
|
||||
@@ -24,12 +26,17 @@ public class ChannelGroupCommandServiceBean implements ChannelGroupCommandServic
|
||||
|
||||
@Override
|
||||
public Boolean isCommandEnabled(ACommand command, AChannel channel) {
|
||||
List<AChannelGroupCommand> allChannelGroupsOfCommand = channelGroupCommandService.getAllGroupCommandsForCommand(command);
|
||||
List<AChannelGroupCommand> allChannelGroupsOfCommand =
|
||||
channelGroupCommandService.getAllGroupCommandsForCommandWithType(command, COMMAND_CHANNEL_GROUP_KEY);
|
||||
for (AChannelGroupCommand aChannelGroupCommand : allChannelGroupsOfCommand) {
|
||||
if(!aChannelGroupCommand.getGroup().getEnabled()) {
|
||||
continue;
|
||||
}
|
||||
Optional<AChannel> channelInGroup = aChannelGroupCommand.getGroup()
|
||||
.getChannels().stream().filter(innerChannel -> innerChannel.getId().equals(channel.getId())).findAny();
|
||||
if (channelInGroup.isPresent() && !aChannelGroupCommand.getEnabled()) {
|
||||
log.debug("Command {} is disabled because the channel is part of group {} in server.", command.getName(), aChannelGroupCommand.getGroup().getId());
|
||||
log.debug("Command {} is disabled because the channel is part of group {} in server.", command.getName(),
|
||||
aChannelGroupCommand.getGroup().getId());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@Getter
|
||||
public class CommandCoolDownRuntimeStorage {
|
||||
// maps server ID to command name to time at which the command can be executed again
|
||||
private Map<Long, CommandReUseMap> serverCoolDowns = new HashMap<>();
|
||||
// maps server ID to channel group ID to command name to time at which the command can be executed again
|
||||
private Map<Long, Map<Long, CommandReUseMap>> channelGroupCoolDowns = new HashMap<>();
|
||||
// maps server ID to member ID to command name to time at which the command can be executed again
|
||||
private Map<Long, Map<Long, CommandReUseMap>> memberCoolDowns = new HashMap<>();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
class CommandReUseMap {
|
||||
private Map<String, Instant> reUseTimes;
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CoolDownCheckResult;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.model.database.CoolDownChannelGroup;
|
||||
import dev.sheldan.abstracto.core.command.service.management.ChannelGroupCommandManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.ServerIdChannelId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroupCommand;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommandCoolDownServiceBean implements CommandCoolDownService {
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownRuntimeStorage storage;
|
||||
|
||||
private static final Lock runTimeLock = new ReentrantLock();
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandInServerManagementService commandInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandManagementService commandManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupCommandManagementService channelGroupCommandService;
|
||||
|
||||
@Autowired
|
||||
private CoolDownChannelGroupManagementService coolDownChannelGroupManagementService;
|
||||
|
||||
public static final String COOL_DOWN_CHANNEL_GROUP_TYPE = "commandCoolDown";
|
||||
|
||||
@Override
|
||||
public void takeLock() {
|
||||
runTimeLock.lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseLock() {
|
||||
runTimeLock.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoolDownCheckResult allowedToExecuteCommand(Command command, CommandContext context) {
|
||||
Long serverId = context.getGuild().getIdLong();
|
||||
Instant now = Instant.now();
|
||||
String commandName = command.getConfiguration().getName();
|
||||
Duration serverCooldown = null;
|
||||
Duration channelCooldown = null;
|
||||
Duration memberCooldown = null;
|
||||
if(storage.getServerCoolDowns().containsKey(serverId)) {
|
||||
CommandReUseMap serverMap = storage.getServerCoolDowns().get(serverId);
|
||||
Duration durationToExecuteIn = getDurationToExecuteIn(now, commandName, serverMap);
|
||||
if (durationIndicatesCoolDown(durationToExecuteIn)) {
|
||||
serverCooldown = durationToExecuteIn;
|
||||
}
|
||||
}
|
||||
if(storage.getChannelGroupCoolDowns().containsKey(serverId)) {
|
||||
Map<Long, CommandReUseMap> serverMap = storage.getChannelGroupCoolDowns().get(serverId);
|
||||
if(!serverMap.keySet().isEmpty()) {
|
||||
Long channelId = context.getChannel().getIdLong();
|
||||
AChannel channel = channelManagementService.loadChannel(channelId);
|
||||
List<AChannelGroup> channelGroups =
|
||||
channelGroupService.getChannelGroupsOfChannelWithType(channel, COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
for (AChannelGroup channelGroup : channelGroups) {
|
||||
if(serverMap.containsKey(channelGroup.getId())) {
|
||||
CommandReUseMap channelGroupMap = serverMap.get(channelGroup.getId());
|
||||
Duration durationToExecuteIn = getDurationToExecuteIn(now, commandName, channelGroupMap);
|
||||
if (durationIndicatesCoolDown(durationToExecuteIn)) {
|
||||
channelCooldown = durationToExecuteIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(storage.getMemberCoolDowns().containsKey(serverId)) {
|
||||
Map<Long, CommandReUseMap> serverMap = storage.getMemberCoolDowns().get(serverId);
|
||||
if(!serverMap.keySet().isEmpty()) {
|
||||
Long memberId = context.getAuthor().getIdLong();
|
||||
if(serverMap.containsKey(memberId)) {
|
||||
CommandReUseMap commandReUseMap = serverMap.get(memberId);
|
||||
Duration durationToExecuteIn = getDurationToExecuteIn(now, commandName, commandReUseMap);
|
||||
if (durationIndicatesCoolDown(durationToExecuteIn)) {
|
||||
memberCooldown = durationToExecuteIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(serverCooldown != null || channelCooldown != null || memberCooldown != null) {
|
||||
Long serverSeconds = serverCooldown != null ? serverCooldown.getSeconds() : 0L;
|
||||
Long channelSeconds = channelCooldown != null ? channelCooldown.getSeconds() : 0L;
|
||||
Long memberSeconds = memberCooldown != null ? memberCooldown.getSeconds() : 0L;
|
||||
if(serverSeconds > channelSeconds && serverSeconds > memberSeconds) {
|
||||
return CoolDownCheckResult.getServerCoolDown(serverCooldown);
|
||||
}
|
||||
if(channelSeconds > serverSeconds && channelSeconds > memberSeconds) {
|
||||
return CoolDownCheckResult.getChannelGroupCoolDown(channelCooldown);
|
||||
}
|
||||
return CoolDownCheckResult.getMemberCoolDown(memberCooldown);
|
||||
}
|
||||
return CoolDownCheckResult.noCoolDown();
|
||||
}
|
||||
|
||||
private boolean durationIndicatesCoolDown(Duration duration) {
|
||||
return !duration.equals(Duration.ZERO) && !duration.isNegative();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getServerCoolDownForCommand(Command command, Long serverId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandConfiguration.getName());
|
||||
return getServerCoolDownForCommand(aCommand, command, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getServerCoolDownForCommand(ACommand aCommand, Command command, Long serverId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
ACommandInAServer commandInServer = commandInServerManagementService.getCommandForServer(aCommand, serverId);
|
||||
if(commandInServer.getCoolDown() != null) {
|
||||
return Duration.ofSeconds(commandInServer.getCoolDown());
|
||||
}
|
||||
if(commandConfiguration.getCoolDownConfig() != null) {
|
||||
return commandConfiguration.getCoolDownConfig().getServerCoolDown();
|
||||
}
|
||||
return Duration.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getChannelGroupCoolDownForCommand(Command command, ServerIdChannelId serverIdChannelId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandConfiguration.getName());
|
||||
return getChannelGroupCoolDownForCommand(aCommand, command, serverIdChannelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getChannelGroupCoolDownForCommand(ACommand aCommand, Command command, ServerIdChannelId serverIdChannelId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
AChannel channel = channelManagementService.loadChannel(serverIdChannelId.getChannelId());
|
||||
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
List<AChannelGroupCommand> allChannelGroupsOfCommand =
|
||||
channelGroupCommandService.getAllGroupCommandsForCommandInGroups(aCommand, channelGroups);
|
||||
if(!allChannelGroupsOfCommand.isEmpty()) {
|
||||
Long durationInSeconds = 0L;
|
||||
if(allChannelGroupsOfCommand.size() > 1) {
|
||||
log.info("Found multiple channel groups of type commandCoolDown for command {} in server {}. ",
|
||||
command.getConfiguration().getName(), serverIdChannelId.getServerId());
|
||||
}
|
||||
for (AChannelGroupCommand channelGroupCommand : allChannelGroupsOfCommand) {
|
||||
CoolDownChannelGroup channelGroup = coolDownChannelGroupManagementService.findByChannelGroupId(channelGroupCommand.getGroup().getId());
|
||||
if (channelGroup.getChannelCoolDown() != null) {
|
||||
durationInSeconds = Math.max(durationInSeconds, channelGroup.getChannelCoolDown());
|
||||
}
|
||||
}
|
||||
return Duration.ofSeconds(durationInSeconds);
|
||||
}
|
||||
if(commandConfiguration.getCoolDownConfig() != null) {
|
||||
return commandConfiguration.getCoolDownConfig().getChannelCoolDown();
|
||||
}
|
||||
return Duration.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getMemberCoolDownForCommand(Command command, ServerIdChannelId serverIdChannelId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandConfiguration.getName());
|
||||
return getMemberCoolDownForCommand(aCommand, command, serverIdChannelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getMemberCoolDownForCommand(ACommand aCommand, Command command, ServerIdChannelId serverIdChannelId) {
|
||||
CommandConfiguration commandConfiguration = command.getConfiguration();
|
||||
AChannel channel = channelManagementService.loadChannel(serverIdChannelId.getChannelId());
|
||||
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
List<AChannelGroupCommand> allChannelGroupsOfCommand =
|
||||
channelGroupCommandService.getAllGroupCommandsForCommandInGroups(aCommand, channelGroups);
|
||||
if(!allChannelGroupsOfCommand.isEmpty()) {
|
||||
Long durationInSeconds = 0L;
|
||||
if(allChannelGroupsOfCommand.size() > 1) {
|
||||
log.info("Found multiple channel groups of type commandCoolDown for command {} in server {}. ",
|
||||
command.getConfiguration().getName(), serverIdChannelId.getServerId());
|
||||
}
|
||||
for (AChannelGroupCommand channelGroupCommand : allChannelGroupsOfCommand) {
|
||||
CoolDownChannelGroup channelGroup = coolDownChannelGroupManagementService.findByChannelGroupId(channelGroupCommand.getGroup().getId());
|
||||
if (channelGroup.getMemberCoolDown() != null) {
|
||||
durationInSeconds = Math.max(durationInSeconds, channelGroup.getMemberCoolDown());
|
||||
}
|
||||
}
|
||||
return Duration.ofSeconds(durationInSeconds);
|
||||
}
|
||||
if(commandConfiguration.getCoolDownConfig() != null) {
|
||||
return commandConfiguration.getCoolDownConfig().getMemberCoolDown();
|
||||
}
|
||||
return Duration.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addServerCoolDown(Command command, Long serverId) {
|
||||
addServerCoolDown(command, serverId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addServerCoolDown(Command command, Long serverId, boolean takeLock) {
|
||||
if(takeLock) {
|
||||
takeLock();
|
||||
}
|
||||
try {
|
||||
Duration coolDown = getServerCoolDownForCommand(command, serverId);
|
||||
Instant newExecutionPoint = Instant.now().plus(coolDown);
|
||||
String commandName = command.getConfiguration().getName();
|
||||
Map<Long, CommandReUseMap> serverCoolDowns = storage.getServerCoolDowns();
|
||||
createReUseMapIfNotExists(newExecutionPoint, commandName, serverCoolDowns, serverId);
|
||||
} finally {
|
||||
if(takeLock) {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannelCoolDown(Command command, ServerIdChannelId serverIdChannelId) {
|
||||
addChannelCoolDown(command, serverIdChannelId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannelCoolDown(Command command, ServerIdChannelId serverIdChannelId, boolean takeLock) {
|
||||
if(takeLock) {
|
||||
takeLock();
|
||||
}
|
||||
try {
|
||||
Duration coolDown = getChannelGroupCoolDownForCommand(command, serverIdChannelId);
|
||||
Instant newExecutionPoint = Instant.now().plus(coolDown);
|
||||
String commandName = command.getConfiguration().getName();
|
||||
Long serverId = serverIdChannelId.getServerId();
|
||||
Map<Long, Map<Long, CommandReUseMap>> serverChannelGroupCoolDowns = storage.getChannelGroupCoolDowns();
|
||||
Map<Long, CommandReUseMap> channelGroupCoolDowns;
|
||||
if(serverChannelGroupCoolDowns.containsKey(serverId)) {
|
||||
channelGroupCoolDowns = serverChannelGroupCoolDowns.get(serverId);
|
||||
} else {
|
||||
channelGroupCoolDowns = new HashMap<>();
|
||||
serverChannelGroupCoolDowns.put(serverId, channelGroupCoolDowns);
|
||||
}
|
||||
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandName);
|
||||
Long channelId = serverIdChannelId.getChannelId();
|
||||
AChannel channel = channelManagementService.loadChannel(channelId);
|
||||
List<AChannelGroup> channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
List<AChannelGroupCommand> allChannelGroupsOfCommand =
|
||||
channelGroupCommandService.getAllGroupCommandsForCommandInGroups(aCommand, channelGroups);
|
||||
if (!allChannelGroupsOfCommand.isEmpty()) {
|
||||
AChannelGroupCommand groupCommand = allChannelGroupsOfCommand.get(0);
|
||||
if (allChannelGroupsOfCommand.size() > 1) {
|
||||
log.info("Found multiple channel groups of type commandCoolDown for command {} in server {}. Taking the command group {}.",
|
||||
command.getConfiguration().getName(), serverId, groupCommand.getCommandInGroupId());
|
||||
}
|
||||
Long channelGroupId = groupCommand.getGroup().getId();
|
||||
if (channelGroupCoolDowns.containsKey(channelGroupId)) {
|
||||
createReUseMapIfNotExists(newExecutionPoint, commandName, channelGroupCoolDowns, channelGroupId);
|
||||
} else {
|
||||
CommandReUseMap commandReUseMap = createCommandReUseMap(newExecutionPoint, commandName);
|
||||
channelGroupCoolDowns.put(channelGroupId, commandReUseMap);
|
||||
}
|
||||
|
||||
} else {
|
||||
log.debug("Not adding a cool down on channel {} in server {}, because there is not channel group configured.",
|
||||
channelId, serverId);
|
||||
}
|
||||
} finally {
|
||||
if(takeLock) {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createReUseMapIfNotExists(Instant newExecutionPoint, String commandName, Map<Long, CommandReUseMap> reuseMapMap, Long mapId) {
|
||||
if (reuseMapMap.containsKey(mapId)) {
|
||||
Map<String, Instant> reUseTimes = reuseMapMap.get(mapId).getReUseTimes();
|
||||
reUseTimes.put(commandName, newExecutionPoint);
|
||||
} else {
|
||||
CommandReUseMap commandReUseMap = createCommandReUseMap(newExecutionPoint, commandName);
|
||||
reuseMapMap.put(mapId, commandReUseMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMemberCoolDown(Command command, AServerChannelUserId serverChannelUserId) {
|
||||
addMemberCoolDown(command, serverChannelUserId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMemberCoolDown(Command command, AServerChannelUserId serverChannelUserId, boolean takeLock) {
|
||||
if(takeLock) {
|
||||
takeLock();
|
||||
}
|
||||
try {
|
||||
Long serverId = serverChannelUserId.getGuildId();
|
||||
Duration coolDown = getMemberCoolDownForCommand(command, serverChannelUserId.toServerChannelId());
|
||||
Instant newExecutionPoint = Instant.now().plus(coolDown);
|
||||
String commandName = command.getConfiguration().getName();
|
||||
Map<Long, Map<Long, CommandReUseMap>> serverMemberCoolDowns = storage.getMemberCoolDowns();
|
||||
Map<Long, CommandReUseMap> memberCoolDowns;
|
||||
if(serverMemberCoolDowns.containsKey(serverId)) {
|
||||
memberCoolDowns = serverMemberCoolDowns.get(serverId);
|
||||
} else {
|
||||
memberCoolDowns = new HashMap<>();
|
||||
serverMemberCoolDowns.put(serverId, memberCoolDowns);
|
||||
}
|
||||
Long userId = serverChannelUserId.getUserId();
|
||||
if (memberCoolDowns.containsKey(userId)) {
|
||||
createReUseMapIfNotExists(newExecutionPoint, commandName, memberCoolDowns, userId);
|
||||
} else {
|
||||
CommandReUseMap commandReUseMap = createCommandReUseMap(newExecutionPoint, commandName);
|
||||
memberCoolDowns.put(userId, commandReUseMap);
|
||||
}
|
||||
} finally {
|
||||
if(takeLock) {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCoolDowns(Command command, CommandContext context) {
|
||||
takeLock();
|
||||
try {
|
||||
AServerChannelUserId contextIds = AServerChannelUserId
|
||||
.builder()
|
||||
.channelId(context.getChannel().getIdLong())
|
||||
.userId(context.getAuthor().getIdLong())
|
||||
.guildId(context.getGuild().getIdLong())
|
||||
.build();
|
||||
addServerCoolDown(command, contextIds.getGuildId(), false);
|
||||
addChannelCoolDown(command, contextIds.toServerChannelId(), false);
|
||||
addMemberCoolDown(command, contextIds, false);
|
||||
} finally {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCoolDownConfigForChannelGroup(AChannelGroup aChannelGroup, Duration groupCoolDown, Duration memberCoolDown) {
|
||||
CoolDownChannelGroup cdChannelGroup = coolDownChannelGroupManagementService.findByChannelGroupId(aChannelGroup.getId());
|
||||
cdChannelGroup.setChannelCoolDown(groupCoolDown.getSeconds());
|
||||
cdChannelGroup.setMemberCoolDown(memberCoolDown.getSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCoolDownsForServer(Long serverId) {
|
||||
takeLock();
|
||||
try {
|
||||
storage.getServerCoolDowns().remove(serverId);
|
||||
storage.getChannelGroupCoolDowns().remove(serverId);
|
||||
storage.getMemberCoolDowns().remove(serverId);
|
||||
} finally {
|
||||
releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
private Duration getDurationToExecuteIn(Instant now, String commandName, CommandReUseMap reuseMap) {
|
||||
if(reuseMap.getReUseTimes().containsKey(commandName)) {
|
||||
Instant reUseTime = reuseMap.getReUseTimes().get(commandName);
|
||||
return Duration.between(now, reUseTime);
|
||||
}
|
||||
return Duration.ZERO;
|
||||
}
|
||||
|
||||
private CommandReUseMap createCommandReUseMap(Instant newExecutionPoint, String commandName) {
|
||||
Map<String, Instant> reUseTimes = new HashMap<>();
|
||||
reUseTimes.put(commandName, newExecutionPoint);
|
||||
return CommandReUseMap.builder().reUseTimes(reUseTimes).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.exception.CommandNotFoundException;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.service.management.ChannelGroupCommandManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
public class CommandDisabledServiceBean implements CommandDisabledService {
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandManagementService commandManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupCommandManagementService channelGroupCommandManagementService;
|
||||
|
||||
@Override
|
||||
public void disableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
ACommand command = commandManagementService.findCommandByName(commandName);
|
||||
if(command == null) {
|
||||
throw new CommandNotFoundException();
|
||||
}
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, COMMAND_CHANNEL_GROUP_KEY);
|
||||
channelGroupCommandManagementService.setCommandInGroupTo(command, channelGroup, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
ACommand command = commandManagementService.findCommandByName(commandName);
|
||||
if(command == null) {
|
||||
throw new CommandNotFoundException();
|
||||
}
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, COMMAND_CHANNEL_GROUP_KEY);
|
||||
channelGroupCommandManagementService.setCommandInGroupTo(command, channelGroup, true);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.command.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.exception.CommandNotFoundInGroupException;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.repository.ChannelGroupCommandRepository;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroupCommand;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -26,7 +26,23 @@ public class ChannelGroupCommandManagementServiceBean implements ChannelGroupCom
|
||||
|
||||
groupCommand.setEnabled(enabled);
|
||||
log.debug("Setting command {} enabled in group {} to {}.", command.getName(), group.getId(), enabled);
|
||||
groupCommandRepository.save(groupCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommandToGroup(ACommand command, AChannelGroup group) {
|
||||
Optional<AChannelGroupCommand> groupCommandOptional = groupCommandRepository.findByCommandAndGroup(command, group);
|
||||
if(!groupCommandOptional.isPresent()) {
|
||||
createCommandInGroup(command, group);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCommandFromGroup(ACommand command, AChannelGroup group) {
|
||||
Optional<AChannelGroupCommand> groupCommandOptional = groupCommandRepository.findByCommandAndGroup(command, group);
|
||||
if(!groupCommandOptional.isPresent()) {
|
||||
throw new CommandNotFoundInGroupException();
|
||||
}
|
||||
groupCommandOptional.ifPresent(channelGroupCommand -> groupCommandRepository.delete(channelGroupCommand));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,7 +52,7 @@ public class ChannelGroupCommandManagementServiceBean implements ChannelGroupCom
|
||||
.command(command)
|
||||
.server(group.getServer())
|
||||
.group(group)
|
||||
.enabled(false)
|
||||
.enabled(true)
|
||||
.build();
|
||||
|
||||
log.info("Creating command {} in group {}.", command.getName(), group.getId());
|
||||
@@ -46,7 +62,7 @@ public class ChannelGroupCommandManagementServiceBean implements ChannelGroupCom
|
||||
|
||||
@Override
|
||||
public AChannelGroupCommand getChannelGroupCommand(ACommand command, AChannelGroup group) {
|
||||
return groupCommandRepository.findByCommandAndGroup(command, group).orElseThrow(() -> new AbstractoRunTimeException("Command not found in group."));
|
||||
return groupCommandRepository.findByCommandAndGroup(command, group).orElseThrow(CommandNotFoundInGroupException::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,5 +70,14 @@ public class ChannelGroupCommandManagementServiceBean implements ChannelGroupCom
|
||||
return groupCommandRepository.findByCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AChannelGroupCommand> getAllGroupCommandsForCommandInGroups(ACommand command, List<AChannelGroup> groups) {
|
||||
return groupCommandRepository.findByCommandAndGroupIn(command, groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AChannelGroupCommand> getAllGroupCommandsForCommandWithType(ACommand command, String channelGroupType) {
|
||||
return groupCommandRepository.findByCommandAndGroup_ChannelGroupType_GroupTypeKey(command, channelGroupType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.abstracto.core.command.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.model.database.CommandDisabledChannelGroup;
|
||||
import dev.sheldan.abstracto.core.command.repository.CommandDisabledChannelGroupRepository;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.service.management.CommandDisabledChannelGroupManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CommandDisabledChannelGroupManagementServiceBean implements CommandDisabledChannelGroupManagementService {
|
||||
|
||||
@Autowired
|
||||
private CommandDisabledChannelGroupRepository commandDisabledChannelGroupRepository;
|
||||
|
||||
@Override
|
||||
public CommandDisabledChannelGroup createCommandDisabledChannelGroup(AChannelGroup channelGroup) {
|
||||
CommandDisabledChannelGroup commandDisabledChannelGroup = CommandDisabledChannelGroup
|
||||
.builder()
|
||||
.channelGroup(channelGroup)
|
||||
.id(channelGroup.getId())
|
||||
.build();
|
||||
log.info("Creating command disabled channel group for channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId());
|
||||
return commandDisabledChannelGroupRepository.save(commandDisabledChannelGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCommandDisabledChannelGroup(AChannelGroup channelGroup) {
|
||||
log.info("Deleting command disabled channel group for channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId());
|
||||
commandDisabledChannelGroupRepository.deleteById(channelGroup.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandDisabledChannelGroup findViaChannelGroup(AChannelGroup channelGroup) {
|
||||
return commandDisabledChannelGroupRepository.getOne(channelGroup.getId());
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ public class CommandInServerManagementServiceBean implements CommandInServerMana
|
||||
.commandReference(command)
|
||||
.serverReference(server)
|
||||
.restricted(false)
|
||||
.coolDown(0L)
|
||||
.build();
|
||||
log.info("Creating command {} in server {}.", command.getName(), server.getId());
|
||||
return repository.save(commandInAServer);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package dev.sheldan.abstracto.core.command.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.model.database.CoolDownChannelGroup;
|
||||
import dev.sheldan.abstracto.core.command.repository.CoolDownChannelGroupRepository;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CoolDownChannelGroupManagementServiceBean implements CoolDownChannelGroupManagementService {
|
||||
|
||||
@Autowired
|
||||
private CoolDownChannelGroupRepository repository;
|
||||
|
||||
@Override
|
||||
public CoolDownChannelGroup createCoolDownChannelGroup(AChannelGroup aChannelGroup) {
|
||||
CoolDownChannelGroup newChannelGroup = CoolDownChannelGroup
|
||||
.builder()
|
||||
.channelGroup(aChannelGroup)
|
||||
.id(aChannelGroup.getId())
|
||||
.memberCoolDown(0L)
|
||||
.channelCoolDown(0L)
|
||||
.build();
|
||||
return repository.save(newChannelGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoolDownChannelGroup findByChannelGroupId(Long channelGroupId) {
|
||||
return repository.getOne(channelGroupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCoolDownChannelGroup(AChannelGroup aChannelGroup) {
|
||||
repository.delete(findByChannelGroupId(aChannelGroup.getId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
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.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class AddCommandToChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
String commandName = (String) commandContext.getParameters().getParameters().get(1);
|
||||
channelGroupService.addCommandToChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
Parameter commandName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, commandName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("addCommandToChannelGroup")
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
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.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DisableChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
channelGroupService.disableChannelGroup(channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("disableChannelGroup")
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandDisabledService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -20,21 +20,21 @@ import java.util.List;
|
||||
public class DisableCommand extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
private CommandDisabledService disableCommandInChannelGroup;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String commandName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(1);
|
||||
channelGroupService.disableCommandInChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
disableCommandInChannelGroup.disableCommandInChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
Parameter channelToAdd = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelToAdd);
|
||||
Parameter commandName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandName, channelGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("disableCommand")
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
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.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class EnableChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
channelGroupService.enableChannelGroup(channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("enableChannelGroup")
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandDisabledService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -20,21 +20,21 @@ import java.util.List;
|
||||
public class EnableCommand extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
private CommandDisabledService commandDisabledService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String commandName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(1);
|
||||
channelGroupService.enableCommandInChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
commandDisabledService.enableCommandInChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
Parameter channelToAdd = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelToAdd);
|
||||
Parameter commandName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
Parameter channelGroupname = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandName, channelGroupname);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).hasExample(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("enableCommand")
|
||||
|
||||
@@ -10,22 +10,18 @@ import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ChannelGroupChannelModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ChannelGroupModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ListChannelGroupsModel;
|
||||
import dev.sheldan.abstracto.core.service.ChannelGroupService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class ListChannelGroups extends AbstractConditionableCommand {
|
||||
@@ -42,41 +38,20 @@ public class ListChannelGroups extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
AServer server = serverManagementService.loadServer(commandContext.getGuild());
|
||||
List<AChannelGroup> channelGroups = channelGroupManagementService.findAllInServer(server);
|
||||
ListChannelGroupsModel template = (ListChannelGroupsModel) ContextConverter.fromCommandContext(commandContext, ListChannelGroupsModel.class);
|
||||
template.setGroups(convertAChannelGroupToChannelGroupChannel(channelGroups));
|
||||
template.setGroups(channelGroupService.convertAChannelGroupToChannelGroupChannel(channelGroups));
|
||||
MessageToSend response = templateService.renderEmbedTemplate("listChannelGroups_response", template, commandContext.getGuild().getIdLong());
|
||||
channelService.sendMessageToSendToChannel(response, commandContext.getChannel());
|
||||
return CommandResult.fromIgnored();
|
||||
}
|
||||
|
||||
private List<ChannelGroupModel> convertAChannelGroupToChannelGroupChannel(List<AChannelGroup> channelGroups) {
|
||||
List<ChannelGroupModel> converted = new ArrayList<>();
|
||||
channelGroups.forEach(group -> {
|
||||
List<ChannelGroupChannelModel> convertedChannels = new ArrayList<>();
|
||||
group.getChannels().forEach(channel -> {
|
||||
Optional<TextChannel> textChannelInGuild = channelService.getTextChannelFromServerOptional(channel.getServer().getId(), channel.getId());
|
||||
ChannelGroupChannelModel convertedChannel = ChannelGroupChannelModel
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.discordChannel(textChannelInGuild.orElse(null))
|
||||
.build();
|
||||
convertedChannels.add(convertedChannel);
|
||||
});
|
||||
ChannelGroupModel channelGroup = ChannelGroupModel
|
||||
.builder()
|
||||
.name(group.getGroupName())
|
||||
.typeKey(group.getChannelGroupType().getGroupTypeKey())
|
||||
.channels(convertedChannels)
|
||||
.build();
|
||||
converted.add(channelGroup);
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<String> aliases = Arrays.asList("lsChGrp");
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.sheldan.abstracto.core.commands.channels;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
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.service.ChannelGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class RemoveCommandFromChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupService channelGroupService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
String channelGroupName = (String) commandContext.getParameters().getParameters().get(0);
|
||||
String commandName = (String) commandContext.getParameters().getParameters().get(1);
|
||||
channelGroupService.removeCommandFromChannelGroup(commandName, channelGroupName, commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").type(String.class).templated(true).build();
|
||||
Parameter commandName = Parameter.builder().name("commandName").type(String.class).templated(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, commandName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("removeCommandFromChannelGroup")
|
||||
.module(ChannelsModuleDefinition.CHANNELS)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.cooldown;
|
||||
|
||||
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.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownService;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ClearCommandCoolDowns extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownService commandCoolDownService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
commandCoolDownService.clearCoolDownsForServer(commandContext.getGuild().getIdLong());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("clearCommandCoolDowns")
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.cooldown;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownService;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownServiceBean;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class CommandCoolDownChannelGroup extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownService coolDownService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
AChannelGroup fakeChannelGroup = (AChannelGroup) parameters.get(0);
|
||||
Duration channelDuration = (Duration) parameters.get(1);
|
||||
Duration memberDuration = (Duration) parameters.get(2);
|
||||
AServer actualServer = serverManagementService.loadServer(commandContext.getGuild().getIdLong());
|
||||
AChannelGroup actualChannelGroup = channelGroupManagementService.findByNameAndServerAndType(
|
||||
fakeChannelGroup.getGroupName(), actualServer, CommandCoolDownServiceBean.COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
coolDownService.setCoolDownConfigForChannelGroup(actualChannelGroup, channelDuration, memberDuration);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter channelGroupName = Parameter.builder().name("channelGroupName").templated(true).type(AChannelGroup.class).build();
|
||||
Parameter channelDuration = Parameter.builder().name("channelDuration").templated(true).type(Duration.class).build();
|
||||
Parameter memberDuration = Parameter.builder().name("memberDuration").templated(true).type(Duration.class).build();
|
||||
List<Parameter> parameters = Arrays.asList(channelGroupName, channelDuration, memberDuration);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("commandCoolDownChannelGroup")
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package dev.sheldan.abstracto.core.commands.config.cooldown;
|
||||
|
||||
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.config.features.CoreFeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.commands.config.ConfigModuleDefinition;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class CommandCoolDownServer extends AbstractConditionableCommand {
|
||||
|
||||
@Autowired
|
||||
private CommandInServerManagementService commandInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandManagementService commandManagementService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String commandName = (String) parameters.get(0);
|
||||
ACommand aCommand = commandManagementService.findCommandByName(commandName);
|
||||
Duration duration = (Duration) parameters.get(1);
|
||||
ACommandInAServer commandForServer = commandInServerManagementService.getCommandForServer(aCommand, commandContext.getGuild().getIdLong());
|
||||
commandForServer.setCoolDown(duration.getSeconds());
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandName = Parameter.builder().name("command").templated(true).type(String.class).build();
|
||||
Parameter coolDownDuration = Parameter.builder().name("duration").templated(true).type(Duration.class).build();
|
||||
List<Parameter> parameters = Arrays.asList(commandName, coolDownDuration);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("commandCoolDownServer")
|
||||
.module(ConfigModuleDefinition.CONFIG)
|
||||
.parameters(parameters)
|
||||
.templated(true)
|
||||
.help(helpInfo)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CoreFeatureDefinition.CORE_FEATURE;
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,14 @@ import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandInServerAliasService;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandRegistry;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandService;
|
||||
import dev.sheldan.abstracto.core.command.service.ModuleRegistry;
|
||||
import dev.sheldan.abstracto.core.command.service.*;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
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.ServerIdChannelId;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.help.HelpCommandDetailsModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.help.HelpModuleDetailsModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.help.HelpModuleOverviewModel;
|
||||
@@ -31,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -70,6 +69,9 @@ public class Help implements Command {
|
||||
@Autowired
|
||||
private CommandInServerAliasService commandInServerAliasService;
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownService commandCoolDownService;
|
||||
|
||||
public static final String HELP_COMMAND_EXECUTED_METRIC = "help.executions";
|
||||
public static final String CATEGORY = "category";
|
||||
private static final CounterMetric HELP_COMMAND_NO_PARAMETER_METRIC =
|
||||
@@ -133,12 +135,20 @@ public class Help implements Command {
|
||||
if(commandOptional.isPresent()) {
|
||||
metricService.incrementCounter(HELP_COMMAND_COMMAND_METRIC);
|
||||
Command command = commandOptional.get();
|
||||
ServerIdChannelId contextIds = ServerIdChannelId
|
||||
.builder()
|
||||
.channelId(commandContext.getChannel().getIdLong())
|
||||
.serverId(commandContext.getGuild().getIdLong())
|
||||
.build();
|
||||
|
||||
log.debug("Displaying help for command {}.", command.getConfiguration().getName());
|
||||
ACommand aCommand = commandManagementService.findCommandByName(command.getConfiguration().getName());
|
||||
List<String> aliases = commandInServerAliasService.getAliasesForCommand(commandContext.getGuild().getIdLong(), command.getConfiguration().getName());
|
||||
ACommandInAServer aCommandInAServer = commandInServerManagementService.getCommandForServer(aCommand, commandContext.getGuild().getIdLong());
|
||||
HelpCommandDetailsModel model = (HelpCommandDetailsModel) ContextConverter.fromCommandContext(commandContext, HelpCommandDetailsModel.class);
|
||||
model.setServerSpecificAliases(aliases);
|
||||
CommandCoolDownConfig coolDownConfig = getCoolDownConfig(command, contextIds);
|
||||
model.setCooldowns(coolDownConfig);
|
||||
if(Boolean.TRUE.equals(aCommandInAServer.getRestricted())) {
|
||||
model.setImmuneRoles(roleService.getRolesFromGuild(aCommandInAServer.getImmuneRoles()));
|
||||
model.setAllowedRoles(roleService.getRolesFromGuild(aCommandInAServer.getAllowedRoles()));
|
||||
@@ -157,6 +167,24 @@ public class Help implements Command {
|
||||
}
|
||||
}
|
||||
|
||||
private CommandCoolDownConfig getCoolDownConfig(Command command, ServerIdChannelId contextIds) {
|
||||
Duration serverCooldown = commandCoolDownService.getServerCoolDownForCommand(command, contextIds.getServerId());
|
||||
Duration channelCooldown = commandCoolDownService.getChannelGroupCoolDownForCommand(command, contextIds);
|
||||
Duration memberCooldown = commandCoolDownService.getMemberCoolDownForCommand(command, contextIds);
|
||||
boolean hasMemberCooldown = !memberCooldown.equals(Duration.ZERO);
|
||||
boolean hasServerCoolDown = !serverCooldown.equals(Duration.ZERO);
|
||||
boolean hasChannelCoolDown = !channelCooldown.equals(Duration.ZERO);
|
||||
if(!hasMemberCooldown && !hasServerCoolDown && !hasChannelCoolDown) {
|
||||
return null;
|
||||
}
|
||||
return CommandCoolDownConfig
|
||||
.builder()
|
||||
.memberCoolDown(hasMemberCooldown ? memberCooldown : null)
|
||||
.serverCoolDown(hasServerCoolDown ? serverCooldown: null)
|
||||
.channelCoolDown(hasChannelCoolDown ? channelCooldown: null)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CompletableFuture<CommandResult> displayHelpOverview(CommandContext commandContext) {
|
||||
log.debug("Displaying help overview response.");
|
||||
ModuleDefinition moduleDefinition = moduleService.getDefaultModule();
|
||||
|
||||
@@ -107,11 +107,6 @@ public class ListenerExecutorConfig {
|
||||
return executorService.setupExecutorFor("channelGroupCreatedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "channelGroupDeletedExecutor")
|
||||
public TaskExecutor channelGroupDeletedExecutor() {
|
||||
return executorService.setupExecutorFor("channelGroupDeletedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "serverJoinExecutor")
|
||||
public TaskExecutor serverJoinExecutor() {
|
||||
return executorService.setupExecutorFor("serverJoinListener");
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupCreatedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupCreatedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CommandDisabledChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
public class AsyncCommandDisabledChannelGroupCreatedListener implements AsyncChannelGroupCreatedListener {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private CommandDisabledChannelGroupManagementService commandDisabledChannelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupCreatedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(COMMAND_CHANNEL_GROUP_KEY)) {
|
||||
commandDisabledChannelGroupManagementService.createCommandDisabledChannelGroup(channelGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupCreatedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupCreatedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.service.CommandCoolDownServiceBean.COOL_DOWN_CHANNEL_GROUP_TYPE;
|
||||
|
||||
@Component
|
||||
public class AsyncCoolDownChannelGroupCreatedListener implements AsyncChannelGroupCreatedListener {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private CoolDownChannelGroupManagementService coolDownChannelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupCreatedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(COOL_DOWN_CHANNEL_GROUP_TYPE)) {
|
||||
coolDownChannelGroupManagementService.createCoolDownChannelGroup(channelGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CommandDisabledChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
public class CommandDisabledChannelGroupDeletedListener implements ChannelGroupDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandDisabledChannelGroupManagementService commandDisabledChannelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupDeletedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(COMMAND_CHANNEL_GROUP_KEY)) {
|
||||
commandDisabledChannelGroupManagementService.deleteCommandDisabledChannelGroup(channelGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.service.CommandCoolDownServiceBean.COOL_DOWN_CHANNEL_GROUP_TYPE;
|
||||
|
||||
@Component
|
||||
public class CoolDownChannelGroupDeletedListener implements ChannelGroupDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private ChannelGroupManagementService channelGroupManagementService;
|
||||
|
||||
@Autowired
|
||||
private CoolDownChannelGroupManagementService coolDownChannelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ChannelGroupDeletedListenerModel model) {
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId());
|
||||
if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(COOL_DOWN_CHANNEL_GROUP_TYPE)) {
|
||||
coolDownChannelGroupManagementService.deleteCoolDownChannelGroup(channelGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ListenerService;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class AsyncChannelGroupDeletedListenerManager {
|
||||
@Autowired(required = false)
|
||||
private List<AsyncChannelGroupDeletedListener> listener;
|
||||
|
||||
@Autowired
|
||||
private ListenerService listenerService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("channelGroupDeletedExecutor")
|
||||
private TaskExecutor channelGroupDeletedExecutor;
|
||||
|
||||
@TransactionalEventListener
|
||||
public void executeListener(ChannelGroupDeletedListenerModel model){
|
||||
listener.forEach(channelGroupCreatedListener ->
|
||||
listenerService.executeListener(channelGroupCreatedListener, model, channelGroupDeletedExecutor)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ListenerService;
|
||||
import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class SyncChannelGroupDeletedListenerManager {
|
||||
@Autowired(required = false)
|
||||
private List<ChannelGroupDeletedListener> listener;
|
||||
|
||||
@Autowired
|
||||
private ListenerService listenerService;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeListener(ChannelGroupDeletedListenerModel model){
|
||||
listener.forEach(channelGroupCreatedListener ->
|
||||
listenerService.executeListener(channelGroupCreatedListener, model)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.abstracto.core.provider;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.model.database.CoolDownChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.provider.ChannelGroupInformationRequest;
|
||||
import dev.sheldan.abstracto.core.models.provider.CoolDownChannelInformation;
|
||||
import dev.sheldan.abstracto.core.models.provider.InformationRequest;
|
||||
import dev.sheldan.abstracto.core.models.provider.ProviderInformation;
|
||||
import dev.sheldan.abstracto.core.service.management.CoolDownChannelGroupManagementService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.service.CommandCoolDownServiceBean.COOL_DOWN_CHANNEL_GROUP_TYPE;
|
||||
|
||||
@Component
|
||||
public class CoolDownChannelGroupInformationProviderBean implements ChannelGroupInformationProvider {
|
||||
|
||||
@Autowired
|
||||
private CoolDownChannelGroupManagementService coolDownChannelGroupManagementService;
|
||||
|
||||
@Override
|
||||
public boolean handlesRequest(InformationRequest informationRequest) {
|
||||
if(informationRequest instanceof ChannelGroupInformationRequest) {
|
||||
ChannelGroupInformationRequest request = (ChannelGroupInformationRequest) informationRequest;
|
||||
return request.getChannelGroupType().equals(COOL_DOWN_CHANNEL_GROUP_TYPE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProviderInformation retrieveInformation(InformationRequest informationRequest) {
|
||||
ChannelGroupInformationRequest request = (ChannelGroupInformationRequest) informationRequest;
|
||||
CoolDownChannelGroup coolDownChannelGroup = coolDownChannelGroupManagementService.findByChannelGroupId(request.getChannelGroupId());
|
||||
return CoolDownChannelInformation
|
||||
.builder()
|
||||
.channelCoolDown(coolDownChannelGroup.getChannelCoolDown())
|
||||
.memberCoolDown(coolDownChannelGroup.getMemberCoolDown())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import java.util.Optional;
|
||||
@Repository
|
||||
public interface ChannelGroupRepository extends JpaRepository<AChannelGroup, Long> {
|
||||
|
||||
Optional<AChannelGroup> findByGroupNameAndServer(String name, AServer server);
|
||||
Optional<AChannelGroup> findByGroupNameIgnoreCaseAndServer(String name, AServer server);
|
||||
|
||||
Optional<AChannelGroup> findByGroupNameAndServerAndChannelGroupType_GroupTypeKey(String name, AServer server, String groupTyeKey);
|
||||
|
||||
@@ -20,7 +20,7 @@ public interface ChannelGroupRepository extends JpaRepository<AChannelGroup, Lon
|
||||
|
||||
List<AChannelGroup> findByServer(AServer server);
|
||||
|
||||
boolean existsByGroupNameAndServer(String name, AServer server);
|
||||
boolean existsByGroupNameIgnoreCaseAndServer(String name, AServer server);
|
||||
|
||||
List<AChannelGroup> findAllByChannels(AChannel channel);
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface ChannelGroupTypeRepository extends JpaRepository<ChannelGroupType, Integer> {
|
||||
Optional<ChannelGroupType> findByGroupTypeKey(String key);
|
||||
Optional<ChannelGroupType> findByGroupTypeKeyIgnoreCase(String key);
|
||||
}
|
||||
|
||||
@@ -5,23 +5,29 @@ import dev.sheldan.abstracto.core.command.exception.CommandNotFoundException;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.service.management.ChannelGroupCommandManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.ChannelGroupType;
|
||||
import dev.sheldan.abstracto.core.exception.ChannelInMultipleChannelGroupsException;
|
||||
import dev.sheldan.abstracto.core.exception.CommandInMultipleChannelGroupsException;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.models.provider.ChannelGroupInformation;
|
||||
import dev.sheldan.abstracto.core.models.provider.ChannelGroupInformationRequest;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ChannelGroupChannelModel;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.ChannelGroupModel;
|
||||
import dev.sheldan.abstracto.core.provider.ChannelGroupInformationProvider;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
|
||||
@Autowired
|
||||
@@ -39,6 +45,11 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private List<ChannelGroupInformationProvider> channelGroupInformationProviders;
|
||||
|
||||
@Override
|
||||
public AChannelGroup createChannelGroup(String name, Long serverId, ChannelGroupType channelGroupType) {
|
||||
@@ -70,6 +81,12 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
if(channelGroup == null) {
|
||||
throw new ChannelGroupNotFoundException(channelGroupName, channelGroupManagementService.getAllAvailableAsString(server));
|
||||
}
|
||||
if(!channelGroup.getChannelGroupType().getAllowsChannelsInMultiple()) {
|
||||
List<AChannelGroup> existingGroups = getChannelGroupsOfChannelWithType(channel, channelGroup.getChannelGroupType().getGroupTypeKey());
|
||||
if(!existingGroups.isEmpty()) {
|
||||
throw new ChannelInMultipleChannelGroupsException(existingGroups.get(0).getGroupName());
|
||||
}
|
||||
}
|
||||
channelGroupManagementService.addChannelToChannelGroup(channelGroup, channel);
|
||||
}
|
||||
|
||||
@@ -95,25 +112,50 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
public void addCommandToChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, COMMAND_CHANNEL_GROUP_KEY);
|
||||
ACommand command = commandManagementService.findCommandByName(commandName);
|
||||
if(command == null) {
|
||||
throw new CommandNotFoundException();
|
||||
}
|
||||
channelGroupCommandManagementService.setCommandInGroupTo(command, channelGroup, false);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServer(channelGroupName, server);
|
||||
if(!channelGroup.getChannelGroupType().getAllowsCommandsInMultiple()) {
|
||||
List<AChannelGroupCommand> existingChannelGroupCommands = channelGroupCommandManagementService
|
||||
.getAllGroupCommandsForCommandWithType(command, channelGroup.getChannelGroupType().getGroupTypeKey());
|
||||
if(!existingChannelGroupCommands.isEmpty()) {
|
||||
throw new CommandInMultipleChannelGroupsException(existingChannelGroupCommands.get(0).getGroup().getGroupName());
|
||||
}
|
||||
}
|
||||
channelGroupCommandManagementService.addCommandToGroup(command, channelGroup);
|
||||
log.info("Adding command {} to channel group {}.", command.getId(), channelGroup.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
public void removeCommandFromChannelGroup(String commandName, String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, COMMAND_CHANNEL_GROUP_KEY);
|
||||
ACommand command = commandManagementService.findCommandByName(commandName);
|
||||
if(command == null) {
|
||||
throw new CommandNotFoundException();
|
||||
}
|
||||
channelGroupCommandManagementService.setCommandInGroupTo(command, channelGroup, true);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServer(channelGroupName, server);
|
||||
channelGroupCommandManagementService.removeCommandFromGroup(command, channelGroup);
|
||||
log.info("Removing command {} from channel group {}.", command.getId(), channelGroup.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableChannelGroup(String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServer(channelGroupName, server);
|
||||
log.info("Disabling channel group {} in server {}.", channelGroup.getId(), serverId);
|
||||
channelGroup.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableChannelGroup(String channelGroupName, Long serverId) {
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServer(channelGroupName, server);
|
||||
log.info("Enabling channel group {} in server {}.", channelGroup.getId(), serverId);
|
||||
channelGroup.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,4 +172,48 @@ public class ChannelGroupServiceBean implements ChannelGroupService {
|
||||
.filter(aChannelGroup -> aChannelGroup.getChannelGroupType().getGroupTypeKey().equals(groupTypeKey))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChannelGroupModel> convertAChannelGroupToChannelGroupChannel(List<AChannelGroup> channelGroups) {
|
||||
List<ChannelGroupModel> converted = new ArrayList<>();
|
||||
channelGroups.forEach(group -> {
|
||||
List<ChannelGroupChannelModel> convertedChannels = new ArrayList<>();
|
||||
group.getChannels().forEach(channel -> {
|
||||
Optional<TextChannel> textChannelInGuild = channelService.getTextChannelFromServerOptional(channel.getServer().getId(), channel.getId());
|
||||
ChannelGroupChannelModel convertedChannel = ChannelGroupChannelModel
|
||||
.builder()
|
||||
.channel(channel)
|
||||
.discordChannel(textChannelInGuild.orElse(null))
|
||||
.build();
|
||||
convertedChannels.add(convertedChannel);
|
||||
});
|
||||
ChannelGroupModel channelGroup = ChannelGroupModel
|
||||
.builder()
|
||||
.name(group.getGroupName())
|
||||
.typeKey(group.getChannelGroupType().getGroupTypeKey())
|
||||
.channels(convertedChannels)
|
||||
.enabled(group.getEnabled())
|
||||
.channelGroupInformation(getAdditionalInformation(group))
|
||||
.build();
|
||||
converted.add(channelGroup);
|
||||
});
|
||||
return converted;
|
||||
}
|
||||
|
||||
private ChannelGroupInformation getAdditionalInformation(AChannelGroup channelGroup) {
|
||||
if(channelGroupInformationProviders == null) {
|
||||
return null;
|
||||
}
|
||||
ChannelGroupInformationRequest request = ChannelGroupInformationRequest
|
||||
.builder()
|
||||
.channelGroupId(channelGroup.getId())
|
||||
.channelGroupType(channelGroup.getChannelGroupType().getGroupTypeKey())
|
||||
.build();
|
||||
for (ChannelGroupInformationProvider provider : channelGroupInformationProviders) {
|
||||
if(provider.handlesRequest(request)) {
|
||||
return provider.retrieveInformation(request);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.core.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.exception.*;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.AsyncChannelGroupCreatedListenerManager;
|
||||
import dev.sheldan.abstracto.core.listener.async.entity.AsyncChannelGroupDeletedListenerManager;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.SyncChannelGroupDeletedListenerManager;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
@@ -31,7 +31,7 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private AsyncChannelGroupDeletedListenerManager deletedListenerManager;
|
||||
private SyncChannelGroupDeletedListenerManager deletedListenerManager;
|
||||
|
||||
@Autowired
|
||||
private AsyncChannelGroupCreatedListenerManager createdListenerManager;
|
||||
@@ -41,7 +41,6 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
|
||||
@Override
|
||||
public AChannelGroup createChannelGroup(String name, AServer server, ChannelGroupType channelGroupType) {
|
||||
name = name.toLowerCase();
|
||||
if(doesChannelGroupExist(name, server)) {
|
||||
throw new ChannelGroupExistsException(name);
|
||||
}
|
||||
@@ -50,6 +49,7 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
.groupName(name)
|
||||
.channelGroupType(channelGroupType)
|
||||
.server(server)
|
||||
.enabled(true)
|
||||
.build();
|
||||
log.info("Creating new channel group in server {}.", server.getId());
|
||||
channelGroup = channelGroupRepository.save(channelGroup);
|
||||
@@ -74,7 +74,7 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
|
||||
@Override
|
||||
public boolean doesChannelGroupExist(String name, AServer server) {
|
||||
return channelGroupRepository.existsByGroupNameAndServer(name, server);
|
||||
return channelGroupRepository.existsByGroupNameIgnoreCaseAndServer(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,9 +85,11 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
throw new ChannelGroupNotFoundException(name, getAllAvailableAsString(server));
|
||||
}
|
||||
log.info("Deleting channel group {} in server {}.", existing.getId(), server.getId());
|
||||
channelGroupRepository.delete(existing);
|
||||
// we need to execute the _sync_ listeners before actually deleting it, in order to allow others to delete their instance
|
||||
// this is a strong binding to listeners, might need to remove the direct connection at some point
|
||||
ChannelGroupDeletedListenerModel model = getDeletionModel(existing);
|
||||
applicationEventPublisher.publishEvent(model);
|
||||
deletedListenerManager.executeListener(model);
|
||||
channelGroupRepository.delete(existing);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,13 +128,13 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
@Override
|
||||
public AChannelGroup findByNameAndServer(String name, AServer server) {
|
||||
String lowerCaseName = name.toLowerCase();
|
||||
return channelGroupRepository.findByGroupNameAndServer(lowerCaseName, server)
|
||||
return channelGroupRepository.findByGroupNameIgnoreCaseAndServer(lowerCaseName, server)
|
||||
.orElseThrow(() -> new ChannelGroupNotFoundException(name, getAllAvailableAsString(server)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AChannelGroup> findByNameAndServerOptional(String name, AServer server) {
|
||||
return channelGroupRepository.findByGroupNameAndServer(name, server);
|
||||
return channelGroupRepository.findByGroupNameIgnoreCaseAndServer(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +142,7 @@ public class ChannelGroupManagementServiceBean implements ChannelGroupManagement
|
||||
String lowerName = name.toLowerCase();
|
||||
Optional<AChannelGroup> channelOptional = channelGroupRepository.findByGroupNameAndServerAndChannelGroupType_GroupTypeKey(lowerName, server, expectedType);
|
||||
return channelOptional.orElseThrow(() -> {
|
||||
if(channelGroupRepository.existsByGroupNameAndServer(lowerName, server)) {
|
||||
if(channelGroupRepository.existsByGroupNameIgnoreCaseAndServer(lowerName, server)) {
|
||||
return new ChannelGroupIncorrectTypeException(name.toLowerCase(), expectedType);
|
||||
} else {
|
||||
List<String> channelGroupNames = extractChannelGroupNames(findAllInServerWithType(server.getId(), expectedType));
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ChannelGroupTypeManagementServiceBean implements ChannelGroupTypeMa
|
||||
|
||||
@Override
|
||||
public Optional<ChannelGroupType> findChannelGroupTypeByKeyOptional(String key) {
|
||||
return repository.findByGroupTypeKey(key);
|
||||
return repository.findByGroupTypeKeyIgnoreCase(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../dbchangelog-3.8.xsd" >
|
||||
<include file="core-tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="core-seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="cool_down_channel_group_type-insertion">
|
||||
<insert tableName="channel_group_type">
|
||||
<column name="group_type_key" value="commandCoolDown"/>
|
||||
<column name="allows_channel_in_multiple" value="false"/>
|
||||
<column name="allows_commands_in_multiple" value="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<property name="coreFeature" value="(SELECT id FROM feature WHERE key = 'core')"/>
|
||||
<property name="configModule" value="(SELECT id FROM module WHERE name = 'config')"/>
|
||||
<property name="channelsModule" value="(SELECT id FROM module WHERE name = 'channels')"/>
|
||||
<changeSet author="Sheldan" id="cool_down-commands" >
|
||||
<insert tableName="command">
|
||||
<column name="name" value="commandCoolDownChannelGroup"/>
|
||||
<column name="module_id" valueComputed="${configModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="commandCoolDownServer"/>
|
||||
<column name="module_id" valueComputed="${configModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="addCommandToChannelGroup"/>
|
||||
<column name="module_id" valueComputed="${channelsModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="removeCommandFromChannelGroup"/>
|
||||
<column name="module_id" valueComputed="${channelsModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="clearCommandCoolDowns"/>
|
||||
<column name="module_id" valueComputed="${configModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="enableChannelGroup"/>
|
||||
<column name="module_id" valueComputed="${channelsModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="disableChannelGroup"/>
|
||||
<column name="module_id" valueComputed="${channelsModule}"/>
|
||||
<column name="feature_id" valueComputed="${coreFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="channel_group_type.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="channel_group_command-change_fk_to_channel_group">
|
||||
<dropForeignKeyConstraint baseTableName="channel_group_command" constraintName="fk_channel_group_command_channel_group"/>
|
||||
<addForeignKeyConstraint baseColumnNames="group_id" baseTableName="channel_group_command" constraintName="fk_channel_group_command_channel_group" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel_group" validate="true"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet author="Sheldan" id="channel_group-add_enabled">
|
||||
<addColumn tableName="channel_group" >
|
||||
<column name="enabled" type="BOOLEAN" defaultValue="true"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="channel_group_type-add_allow_multiple_column">
|
||||
<addColumn tableName="channel_group_type" >
|
||||
<column name="allows_channel_in_multiple" type="boolean" defaultValue="true"/>
|
||||
<column name="allows_commands_in_multiple" type="boolean" defaultValue="true"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="command_disabled_channel_group-table">
|
||||
<createTable tableName="command_disabled_channel_group">
|
||||
<column name="id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="id" baseTableName="command_disabled_channel_group" constraintName="fk_command_disabled_channel_group_group_group"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel_group" validate="true"/>
|
||||
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS command_disabled_channel_group_update_trigger ON command_disabled_channel_group;
|
||||
CREATE TRIGGER repost_check_channel_group_update_trigger BEFORE UPDATE ON command_disabled_channel_group FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS command_disabled_channel_group_insert_trigger ON command_disabled_channel_group;
|
||||
CREATE TRIGGER repost_check_channel_group_insert_trigger BEFORE INSERT ON command_disabled_channel_group FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="command_in_server-add_cool_down_column">
|
||||
<addColumn tableName="command_in_server" >
|
||||
<column name="cool_down" type="integer" defaultValue="0"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="cool_down_channel_group-table">
|
||||
<createTable tableName="cool_down_channel_group">
|
||||
<column name="id" type="BIGINT">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="channel_cool_down" type="integer">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="member_cool_down" type="integer">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="id" baseTableName="cool_down_channel_group" constraintName="fk_cool_down_channel_group_group_group"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel_group" validate="true"/>
|
||||
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS cool_down_channel_group_update_trigger ON cool_down_channel_group;
|
||||
CREATE TRIGGER repost_check_channel_group_update_trigger BEFORE UPDATE ON cool_down_channel_group FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS cool_down_channel_group_insert_trigger ON cool_down_channel_group;
|
||||
CREATE TRIGGER repost_check_channel_group_insert_trigger BEFORE INSERT ON cool_down_channel_group FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?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-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="channel_group.xml" relativeToChangelogFile="true"/>
|
||||
<include file="channel_group_type.xml" relativeToChangelogFile="true"/>
|
||||
<include file="cool_down_channel_group.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command_disabled_channel_group.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command_in_server.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -9,8 +9,9 @@
|
||||
<include file="1.0-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.0-templating/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.1-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.0-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.5-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.7-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.8-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.9-core/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -7,6 +7,7 @@ import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.requests.RestAction;
|
||||
import net.dv8tion.jda.internal.utils.concurrent.task.GatewayTask;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -76,28 +77,33 @@ public class MemberParameterHandlerImplTest extends AbstractParameterHandlerTest
|
||||
Assert.assertEquals(member, parsed.join());
|
||||
}
|
||||
|
||||
@Test(expected = AbstractoTemplatedException.class)
|
||||
@Test
|
||||
public void testNotExistingMember() {
|
||||
String input = "test";
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getMembersByName(input, true)).thenReturn(new ArrayList<>());
|
||||
testUnit.handleAsync(getPieceWithValue(input), null, parameter, message, command);
|
||||
GatewayTask task = new GatewayTask(CompletableFuture.completedFuture(new ArrayList()), () -> {});
|
||||
when(guild.retrieveMembersByPrefix(input, 1)).thenReturn(task);
|
||||
CompletableFuture<Object> future = testUnit.handleAsync(getPieceWithValue(input), null, parameter, message, command);
|
||||
Assert.assertTrue(future.isCompletedExceptionally());
|
||||
}
|
||||
|
||||
@Test(expected = AbstractoTemplatedException.class)
|
||||
@Test
|
||||
public void testMultipleFoundMemberByName() {
|
||||
String input = "test";
|
||||
Member secondMember = Mockito.mock(Member.class);
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getMembersByName(input, true)).thenReturn(Arrays.asList(member, secondMember));
|
||||
testUnit.handleAsync(getPieceWithValue(input), null, parameter, message, command);
|
||||
GatewayTask task = new GatewayTask(CompletableFuture.completedFuture(Arrays.asList(member, secondMember)), () -> {});
|
||||
when(guild.retrieveMembersByPrefix(input, 1)).thenReturn(task);
|
||||
CompletableFuture<Object> future = testUnit.handleAsync(getPieceWithValue(input), null, parameter, message, command);
|
||||
Assert.assertTrue(future.isCompletedExceptionally());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMemberByName() {
|
||||
String input = "test";
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getMembersByName(input, true)).thenReturn(Arrays.asList(member));
|
||||
GatewayTask task = new GatewayTask(CompletableFuture.completedFuture(Arrays.asList(member)), () -> {});
|
||||
when(guild.retrieveMembersByPrefix(input, 1)).thenReturn(task);
|
||||
CompletableFuture<Object> future = testUnit.handleAsync(getPieceWithValue(input), null, parameter, message, command);
|
||||
Member returnedMember = (Member) future.join();
|
||||
Assert.assertFalse(future.isCompletedExceptionally());
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static dev.sheldan.abstracto.core.command.CommandConstants.COMMAND_CHANNEL_GROUP_KEY;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -50,14 +51,15 @@ public class ChannelGroupCommandServiceBeanTest {
|
||||
|
||||
@Test
|
||||
public void testNoChannelGroup() {
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommand(command)).thenReturn(new ArrayList<>());
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommandWithType(command, COMMAND_CHANNEL_GROUP_KEY)).thenReturn(new ArrayList<>());
|
||||
Assert.assertTrue(testUnit.isCommandEnabled(command, channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneDisabledChannelGroup() {
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommand(command)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommandWithType(command, COMMAND_CHANNEL_GROUP_KEY)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommand.getGroup()).thenReturn(channelGroup);
|
||||
when(channelGroup.getEnabled()).thenReturn(true);
|
||||
when(channelGroup.getChannels()).thenReturn(Arrays.asList(channel));
|
||||
when(channelGroupCommand.getEnabled()).thenReturn(false);
|
||||
Assert.assertFalse(testUnit.isCommandEnabled(command, channel));
|
||||
@@ -65,8 +67,9 @@ public class ChannelGroupCommandServiceBeanTest {
|
||||
|
||||
@Test
|
||||
public void testOneEnabledChannelGroup() {
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommand(command)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommandWithType(command, COMMAND_CHANNEL_GROUP_KEY)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommand.getGroup()).thenReturn(channelGroup);
|
||||
when(channelGroup.getEnabled()).thenReturn(true);
|
||||
when(channelGroup.getChannels()).thenReturn(Arrays.asList(channel));
|
||||
when(channelGroupCommand.getEnabled()).thenReturn(true);
|
||||
Assert.assertTrue(testUnit.isCommandEnabled(command, channel));
|
||||
@@ -74,8 +77,9 @@ public class ChannelGroupCommandServiceBeanTest {
|
||||
|
||||
@Test
|
||||
public void testDisabledInOneGroupChannelIsNotPartOf() {
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommand(command)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommandService.getAllGroupCommandsForCommandWithType(command, COMMAND_CHANNEL_GROUP_KEY)).thenReturn(Arrays.asList(channelGroupCommand));
|
||||
when(channelGroupCommand.getGroup()).thenReturn(channelGroup);
|
||||
when(channelGroup.getEnabled()).thenReturn(true);
|
||||
when(channelGroup.getChannels()).thenReturn(Arrays.asList(secondChannel));
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
when(secondChannel.getId()).thenReturn(CHANNEL_ID_2);
|
||||
|
||||
@@ -32,10 +32,14 @@ public abstract class AbstractConditionableCommand implements ConditionalCommand
|
||||
@Autowired
|
||||
private AdminModeCondition adminModeCondition;
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownCondition coolDownCondition;
|
||||
|
||||
|
||||
@Override
|
||||
public List<CommandCondition> getConditions() {
|
||||
return new ArrayList<>(Arrays.asList(adminModeCondition, featureEnabledCondition, commandDisabledCondition, commandDisallowedCondition, featureModeCondition));
|
||||
return new ArrayList<>(Arrays.asList(adminModeCondition, featureEnabledCondition, commandDisabledCondition,
|
||||
commandDisallowedCondition, featureModeCondition, coolDownCondition));
|
||||
}
|
||||
|
||||
protected void checkParameters(CommandContext context) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.sheldan.abstracto.core.command.condition;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.condition.detail.CommandCoolDownDetail;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CoolDownCheckResult;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandCoolDownService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Component
|
||||
public class CommandCoolDownCondition implements CommandCondition {
|
||||
|
||||
@Autowired
|
||||
private CommandCoolDownService commandCoolDownService;
|
||||
|
||||
@Override
|
||||
public ConditionResult shouldExecute(CommandContext commandContext, Command command) {
|
||||
commandCoolDownService.takeLock();
|
||||
try {
|
||||
CoolDownCheckResult result = commandCoolDownService.allowedToExecuteCommand(command, commandContext);
|
||||
if(result.getCanExecute()) {
|
||||
return ConditionResult.builder().result(true).build();
|
||||
} else {
|
||||
if(result.getExecuteIn().compareTo(Duration.ofSeconds(1)) < 0) {
|
||||
result.setExecuteIn(Duration.ofSeconds(1));
|
||||
}
|
||||
return ConditionResult.builder().result(false).conditionDetail(new CommandCoolDownDetail(result)).build();
|
||||
}
|
||||
} finally {
|
||||
commandCoolDownService.releaseLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.sheldan.abstracto.core.command.condition.detail;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionDetail;
|
||||
import dev.sheldan.abstracto.core.command.execution.CoolDownCheckResult;
|
||||
import dev.sheldan.abstracto.core.command.model.condition.CommandCoolDownDetailModel;
|
||||
|
||||
public class CommandCoolDownDetail implements ConditionDetail {
|
||||
|
||||
private final CommandCoolDownDetailModel model;
|
||||
|
||||
public CommandCoolDownDetail(CoolDownCheckResult result) {
|
||||
this.model = CommandCoolDownDetailModel.builder().reason(result).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "command_cool_down_detail";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,8 @@ public class CommandConfiguration {
|
||||
private boolean templated = false;
|
||||
private HelpInfo help;
|
||||
|
||||
private CommandCoolDownConfig coolDownConfig;
|
||||
|
||||
public int getNecessaryParameterCount(){
|
||||
return (int) parameters.stream().filter(parameter -> !parameter.isOptional()).count();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package dev.sheldan.abstracto.core.command.config;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CommandCoolDownConfig {
|
||||
private Duration serverCoolDown;
|
||||
private Duration channelCoolDown;
|
||||
private Duration memberCoolDown;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public class ChannelGroupIncorrectTypeException extends AbstractoRunTimeExceptio
|
||||
}
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "channel_group_not_found_exception";
|
||||
return "channel_group_incorrect_type_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,6 +9,7 @@ public class CommandAliasAlreadyExistsException extends AbstractoRunTimeExceptio
|
||||
private final CommandAliasAlreadyExistsModel model;
|
||||
|
||||
public CommandAliasAlreadyExistsException(String existingCommand) {
|
||||
super("Command alias already exists.");
|
||||
this.model = CommandAliasAlreadyExistsModel
|
||||
.builder()
|
||||
.existingCommand(existingCommand)
|
||||
|
||||
@@ -2,11 +2,13 @@ package dev.sheldan.abstracto.core.command.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class CommandAliasDoesNotExistsException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
public CommandAliasDoesNotExistsException() {
|
||||
super("Command Alias does not exist.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "command_in_server_alias_not_exists_exists_exception";
|
||||
|
||||
@@ -9,6 +9,7 @@ public class CommandAliasHidesCommandException extends AbstractoRunTimeException
|
||||
private final CommandAliasHidesCommandModel model;
|
||||
|
||||
public CommandAliasHidesCommandException(String existingCommand) {
|
||||
super("Command alias hides existing command");
|
||||
this.model = CommandAliasHidesCommandModel
|
||||
.builder()
|
||||
.existingCommand(existingCommand)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.abstracto.core.command.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class CommandNotFoundInGroupException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
public CommandNotFoundInGroupException() {
|
||||
super("Command was not found in given group.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "command_not_found_in_group_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ public class CommandParameterValidationException extends AbstractoRunTimeExcepti
|
||||
private final CommandParameterValidationExceptionModel model;
|
||||
|
||||
public CommandParameterValidationException(List<ValidatorParam> validatorParams, String template, Parameter parameter) {
|
||||
super("Command parameter failed to validate.");
|
||||
this.model = CommandParameterValidationExceptionModel
|
||||
.builder()
|
||||
.validationTemplate(template)
|
||||
|
||||
@@ -12,7 +12,12 @@ public class IncorrectFeatureModeException extends AbstractoRunTimeException imp
|
||||
private final IncorrectFeatureModeModel model;
|
||||
|
||||
public IncorrectFeatureModeException(FeatureDefinition featureDefinition, List<FeatureMode> requiredModes) {
|
||||
this.model = IncorrectFeatureModeModel.builder().featureDefinition(featureDefinition).requiredModes(requiredModes).build();
|
||||
super("Incorrect feature mode.");
|
||||
this.model = IncorrectFeatureModeModel
|
||||
.builder()
|
||||
.featureDefinition(featureDefinition)
|
||||
.requiredModes(requiredModes)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,11 @@ public class IncorrectParameterException extends AbstractoRunTimeException imple
|
||||
|
||||
public IncorrectParameterException(Command command, String parameterName) {
|
||||
super("Incorrect parameter given for parameter");
|
||||
this.model = IncorrectParameterExceptionModel.builder().parameterName(parameterName).command(command).build();
|
||||
this.model = IncorrectParameterExceptionModel
|
||||
.builder()
|
||||
.parameterName(parameterName)
|
||||
.command(command)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package dev.sheldan.abstracto.core.command.execution;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CoolDownCheckResult {
|
||||
private Duration executeIn;
|
||||
private Boolean canExecute;
|
||||
private CoolDownReason reason;
|
||||
|
||||
public static CoolDownCheckResult getServerCoolDown(Duration duration) {
|
||||
return CoolDownCheckResult
|
||||
.builder()
|
||||
.canExecute(false)
|
||||
.reason(CoolDownReason.SERVER)
|
||||
.executeIn(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static CoolDownCheckResult getChannelGroupCoolDown(Duration duration) {
|
||||
return CoolDownCheckResult
|
||||
.builder()
|
||||
.canExecute(false)
|
||||
.reason(CoolDownReason.CHANNEL_GROUP)
|
||||
.executeIn(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static CoolDownCheckResult getMemberCoolDown(Duration duration) {
|
||||
return CoolDownCheckResult
|
||||
.builder()
|
||||
.canExecute(false)
|
||||
.reason(CoolDownReason.MEMBER)
|
||||
.executeIn(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static CoolDownCheckResult noCoolDown() {
|
||||
return CoolDownCheckResult
|
||||
.builder()
|
||||
.canExecute(true)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
enum CoolDownReason {
|
||||
SERVER, CHANNEL_GROUP, MEMBER
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.command.model.condition;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.execution.CoolDownCheckResult;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CommandCoolDownDetailModel implements Serializable {
|
||||
private CoolDownCheckResult reason;
|
||||
}
|
||||
@@ -61,6 +61,9 @@ public class ACommandInAServer implements Serializable {
|
||||
@Column(name = "updated")
|
||||
private Instant updated;
|
||||
|
||||
@Column(name = "cool_down")
|
||||
private Long coolDown;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.core.command.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "command_disabled_channel_group")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class CommandDisabledChannelGroup {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@PrimaryKeyJoinColumn
|
||||
private AChannelGroup channelGroup;
|
||||
|
||||
@Column(name = "created")
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated")
|
||||
private Instant updated;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package dev.sheldan.abstracto.core.command.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "cool_down_channel_group")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class CoolDownChannelGroup {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@PrimaryKeyJoinColumn
|
||||
private AChannelGroup channelGroup;
|
||||
|
||||
@Column(name = "channel_cool_down")
|
||||
private Long channelCoolDown;
|
||||
|
||||
@Column(name = "member_cool_down")
|
||||
private Long memberCoolDown;
|
||||
|
||||
@Column(name = "created")
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated")
|
||||
private Instant updated;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CoolDownCheckResult;
|
||||
import dev.sheldan.abstracto.core.command.model.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
|
||||
import dev.sheldan.abstracto.core.models.ServerIdChannelId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public interface CommandCoolDownService {
|
||||
/**
|
||||
* Acquires the lock which should be used when accessing the runtime storage
|
||||
*/
|
||||
void takeLock();
|
||||
|
||||
/**
|
||||
* Releases the lock which should be used then accessing the runtime storage
|
||||
*/
|
||||
void releaseLock();
|
||||
CoolDownCheckResult allowedToExecuteCommand(Command command, CommandContext context);
|
||||
Duration getServerCoolDownForCommand(Command command, Long serverId);
|
||||
Duration getServerCoolDownForCommand(ACommand aCommand, Command command, Long serverId);
|
||||
Duration getChannelGroupCoolDownForCommand(Command command, ServerIdChannelId serverIdChannelId);
|
||||
Duration getChannelGroupCoolDownForCommand(ACommand aCommand, Command command, ServerIdChannelId serverIdChannelId);
|
||||
Duration getMemberCoolDownForCommand(Command command, ServerIdChannelId serverIdChannelId);
|
||||
Duration getMemberCoolDownForCommand(ACommand aCommand, Command command, ServerIdChannelId serverIdChannelId);
|
||||
void addServerCoolDown(Command command, Long serverId);
|
||||
void addServerCoolDown(Command command, Long serverId, boolean takeLock);
|
||||
void addChannelCoolDown(Command command, ServerIdChannelId context);
|
||||
void addChannelCoolDown(Command command, ServerIdChannelId context, boolean takeLock);
|
||||
void addMemberCoolDown(Command command, AServerChannelUserId context);
|
||||
void addMemberCoolDown(Command command, AServerChannelUserId context, boolean takeLock);
|
||||
void updateCoolDowns(Command command, CommandContext context);
|
||||
void setCoolDownConfigForChannelGroup(AChannelGroup aChannelGroup, Duration groupCoolDown, Duration memberCoolDown);
|
||||
void clearCoolDownsForServer(Long serverId);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
public interface CommandDisabledService {
|
||||
void disableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId);
|
||||
void enableCommandInChannelGroup(String commandName, String channelGroupName, Long serverId);
|
||||
}
|
||||
@@ -8,7 +8,11 @@ import java.util.List;
|
||||
|
||||
public interface ChannelGroupCommandManagementService {
|
||||
void setCommandInGroupTo(ACommand command, AChannelGroup group, Boolean enabled);
|
||||
void addCommandToGroup(ACommand command, AChannelGroup group);
|
||||
void removeCommandFromGroup(ACommand command, AChannelGroup group);
|
||||
AChannelGroupCommand createCommandInGroup(ACommand command, AChannelGroup group);
|
||||
AChannelGroupCommand getChannelGroupCommand(ACommand command, AChannelGroup group);
|
||||
List<AChannelGroupCommand> getAllGroupCommandsForCommand(ACommand command);
|
||||
List<AChannelGroupCommand> getAllGroupCommandsForCommandInGroups(ACommand command, List<AChannelGroup> groups);
|
||||
List<AChannelGroupCommand> getAllGroupCommandsForCommandWithType(ACommand command, String channelGroupType);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ public class CategoryNotFoundException extends AbstractoRunTimeException impleme
|
||||
|
||||
public CategoryNotFoundException(Long categoryId, Long guildId) {
|
||||
super("Category not found");
|
||||
this.model = CategoryNotFoundExceptionModel.builder().categoryId(categoryId).guildId(guildId).build();
|
||||
this.model = CategoryNotFoundExceptionModel
|
||||
.builder()
|
||||
.categoryId(categoryId)
|
||||
.guildId(guildId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,11 @@ public class ChannelGroupTypeNotFound extends AbstractoRunTimeException implemen
|
||||
private final ChannelGroupTypeNotFoundExceptionModel model;
|
||||
|
||||
public ChannelGroupTypeNotFound(List<String> channelGroupTypeKeys) {
|
||||
this.model = ChannelGroupTypeNotFoundExceptionModel.builder().availableGroupTypeKeys(channelGroupTypeKeys).build();
|
||||
super("Channel group type not found.");
|
||||
this.model = ChannelGroupTypeNotFoundExceptionModel
|
||||
.builder()
|
||||
.availableGroupTypeKeys(channelGroupTypeKeys)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.core.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.exception.ChannelInMultipleChannelGroupsExceptionModel;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class ChannelInMultipleChannelGroupsException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
private final ChannelInMultipleChannelGroupsExceptionModel model;
|
||||
|
||||
public ChannelInMultipleChannelGroupsException(String channelGroupName) {
|
||||
super("Channel is already in another group of this type.");
|
||||
this.model = ChannelInMultipleChannelGroupsExceptionModel
|
||||
.builder()
|
||||
.channelGroupName(channelGroupName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "channel_in_multiple_channel_groups_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,10 @@ public class ChannelNotFoundException extends AbstractoRunTimeException implemen
|
||||
|
||||
public ChannelNotFoundException(Long channelId) {
|
||||
super("Channel not found in database");
|
||||
this.model = ChannelNotFoundExceptionModel.builder().channelId(channelId).build();
|
||||
this.model = ChannelNotFoundExceptionModel
|
||||
.builder()
|
||||
.channelId(channelId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,10 @@ public class ChannelNotInGuildException extends AbstractoRunTimeException implem
|
||||
|
||||
public ChannelNotInGuildException(Long channelId) {
|
||||
super("Channel not found in guild");
|
||||
this.model = ChannelNotFoundExceptionModel.builder().channelId(channelId).build();
|
||||
this.model = ChannelNotFoundExceptionModel
|
||||
.builder()
|
||||
.channelId(channelId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.core.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.exception.CommandInMultipleChannelGroupsExceptionModel;
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class CommandInMultipleChannelGroupsException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
private final CommandInMultipleChannelGroupsExceptionModel model;
|
||||
|
||||
public CommandInMultipleChannelGroupsException(String channelGroupName) {
|
||||
super("Command is already in another group of this type.");
|
||||
this.model = CommandInMultipleChannelGroupsExceptionModel
|
||||
.builder()
|
||||
.channelGroupName(channelGroupName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "command_in_multiple_channel_groups_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,10 @@ public class ConfigurationKeyNotFoundException extends AbstractoRunTimeException
|
||||
|
||||
public ConfigurationKeyNotFoundException(String key) {
|
||||
super("Configuration key not found");
|
||||
this.model = ConfigurationKeyNotFoundExceptionModel.builder().key(key).build();
|
||||
this.model = ConfigurationKeyNotFoundExceptionModel
|
||||
.builder()
|
||||
.key(key)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,10 @@ public class ConfiguredEmoteNotUsableException extends AbstractoRunTimeException
|
||||
|
||||
public ConfiguredEmoteNotUsableException(AEmote emote) {
|
||||
super("Emote was configured in database, but is not usable by the bot anymore.");
|
||||
this.model = EmoteConfiguredButNotUsableExceptionModel.builder().emote(emote).build();
|
||||
this.model = EmoteConfiguredButNotUsableExceptionModel
|
||||
.builder()
|
||||
.emote(emote)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,7 +12,11 @@ public class DurationFormatException extends AbstractoRunTimeException implement
|
||||
|
||||
public DurationFormatException(String wrongFormat, List<String> validFormats) {
|
||||
super("Duration format exception ");
|
||||
this.model = DurationFormatExceptionModel.builder().invalidFormat(wrongFormat).validFormats(validFormats).build();
|
||||
this.model = DurationFormatExceptionModel
|
||||
.builder()
|
||||
.invalidFormat(wrongFormat)
|
||||
.validFormats(validFormats)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,10 @@ public class EmoteNotDefinedException extends AbstractoRunTimeException implemen
|
||||
|
||||
public EmoteNotDefinedException(String key) {
|
||||
super(String.format("Emote %s not defined", key));
|
||||
this.model = EmoteNotDefinedExceptionModel.builder().emoteKey(key).build();
|
||||
this.model = EmoteNotDefinedExceptionModel
|
||||
.builder()
|
||||
.emoteKey(key)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,11 @@ public class EmoteNotFoundException extends AbstractoRunTimeException implements
|
||||
|
||||
public EmoteNotFoundException(String key, List<String> availableEmotes) {
|
||||
super("Emote not found");
|
||||
this.model = EmoteNotFoundExceptionModel.builder().emoteKey(key).available(availableEmotes).build();
|
||||
this.model = EmoteNotFoundExceptionModel
|
||||
.builder()
|
||||
.emoteKey(key)
|
||||
.available(availableEmotes)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,10 @@ public class EmoteNotFoundInDbException extends AbstractoRunTimeException implem
|
||||
|
||||
public EmoteNotFoundInDbException(Integer emoteId) {
|
||||
super("Emote not found in database");
|
||||
this.model = EmoteNotFoundInDbExceptionModel.builder().emoteId(emoteId).build();
|
||||
this.model = EmoteNotFoundInDbExceptionModel
|
||||
.builder()
|
||||
.emoteId(emoteId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,10 @@ public class EmoteNotInServerException extends AbstractoRunTimeException impleme
|
||||
|
||||
public EmoteNotInServerException(Long emoteId) {
|
||||
super("Emote not available in server");
|
||||
this.model = EmoteNotInServerExceptionModel.builder().emoteId(emoteId).build();
|
||||
this.model = EmoteNotInServerExceptionModel
|
||||
.builder()
|
||||
.emoteId(emoteId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,10 @@ public class EmoteNotUsableException extends AbstractoRunTimeException implement
|
||||
|
||||
public EmoteNotUsableException(Emote emote) {
|
||||
super(String.format("Emote %s not usable by bot.", emote.getId()));
|
||||
this.model = EmoteNotUsableExceptionModel.builder().emote(emote).build();
|
||||
this.model = EmoteNotUsableExceptionModel
|
||||
.builder()
|
||||
.emote(emote)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,11 @@ public class FeatureModeNotFoundException extends AbstractoRunTimeException impl
|
||||
|
||||
public FeatureModeNotFoundException(String featureMode, List<String> availableModes) {
|
||||
super("Feature mode not found.");
|
||||
this.model = FeatureModeNotFoundExceptionModel.builder().availableModes(availableModes).featureMode(featureMode).build();
|
||||
this.model = FeatureModeNotFoundExceptionModel
|
||||
.builder()
|
||||
.availableModes(availableModes)
|
||||
.featureMode(featureMode)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,8 +11,11 @@ public class FeatureNotFoundException extends AbstractoRunTimeException implemen
|
||||
|
||||
public FeatureNotFoundException(String feature, List<String> availableFeatures) {
|
||||
super("Feature not found.");
|
||||
this.model = FeatureNotFoundExceptionModel.builder().featureName(feature).availableFeatures(availableFeatures).build();
|
||||
|
||||
this.model = FeatureNotFoundExceptionModel
|
||||
.builder()
|
||||
.featureName(feature)
|
||||
.availableFeatures(availableFeatures)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,7 +8,10 @@ public class GuildNotFoundException extends AbstractoRunTimeException implements
|
||||
|
||||
public GuildNotFoundException(Long guildId) {
|
||||
super("Guild not found");
|
||||
this.model = GuildNotFoundExceptionModel.builder().guildId(guildId).build();
|
||||
this.model = GuildNotFoundExceptionModel
|
||||
.builder()
|
||||
.guildId(guildId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.templating.Templatable;
|
||||
|
||||
public class MemberNotFoundException extends AbstractoRunTimeException implements Templatable {
|
||||
|
||||
public MemberNotFoundException() {
|
||||
super("Member was not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "member_not_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,10 @@ public class PostTargetNotFoundException extends AbstractoRunTimeException imple
|
||||
|
||||
public PostTargetNotFoundException(String key) {
|
||||
super("Post target not found");
|
||||
this.model = PostTargetNotFoundExceptionModel.builder().postTargetKey(key).build();
|
||||
this.model = PostTargetNotFoundExceptionModel
|
||||
.builder()
|
||||
.postTargetKey(key)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user