mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-27 14:23:56 +00:00
[AB-154] split up private and guild message received handler, split handlers into async and sync handlers
adapting the tests and improving tests to reduce usage of MockUtils adding some util methods to message bean extending cache for cached messages enabling to build cached messages from messages in DM channels (they are not part of the message cache) splitting multiple listeners to different beans, for better overview (emote updated) adding convenience service for reactions specifically split cached reaction and cached reactions, singular only contains one user, while the later contains all users fixing liquibase configuration for assigned role user fixing assignable role not having a transaction moved caching update a bit earlier in various methods fixing bug that a manual unmute caused duplicate unmute notification fixing short scheduled unmute not checking the new mute state limiting parameters for roll
This commit is contained in:
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.models.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.command.service.management.CommandManagementService;
|
||||
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -162,10 +162,15 @@ public class CommandServiceBean implements CommandService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnParsedCommandParameter getUnParsedCommandParameter(String messageContent) {
|
||||
return new UnParsedCommandParameter(messageContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent) {
|
||||
String contentStripped = messageContainingContent.getContentRaw();
|
||||
UnParsedCommandParameter unParsedParameter = new UnParsedCommandParameter(contentStripped);
|
||||
UnParsedCommandParameter unParsedParameter = getUnParsedCommandParameter(contentStripped);
|
||||
Command command = commandRegistry.findCommandByParameters(commandName, unParsedParameter);
|
||||
return commandReceivedHandler.getParsedParameters(unParsedParameter, command, messageContainingContent);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.core.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:listenerConfig.properties")
|
||||
public class ListenerConfig {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package dev.sheldan.abstracto.core.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
@Configuration
|
||||
public class ListenerExecutorConfig {
|
||||
|
||||
@Value("${abstracto.listener.default.maxPoolSize}")
|
||||
private Integer defaultMaxPoolSize;
|
||||
|
||||
@Value("${abstracto.listener.default.corePoolSize}")
|
||||
private Integer defaultCorePoolSize;
|
||||
|
||||
@Value("${abstracto.listener.default.keepAliveSeconds}")
|
||||
private Integer defaultKeepAliveSeconds;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
private static final String LISTENER_PREFIX = "abstracto.listener.";
|
||||
private static final String LISTENER_MAX_POOL_SIZE = "maxPoolSize";
|
||||
private static final String LISTENER_CORE_POOL_SIZE = "corePoolSize";
|
||||
private static final String LISTENER_KEEP_ALIVE_SECONDS = "keepAliveSeconds";
|
||||
|
||||
@Bean(name = "joinListenerExecutor")
|
||||
public TaskExecutor joinListenerExecutor() {
|
||||
return setupExecutorFor("joinListener");
|
||||
}
|
||||
|
||||
@Bean(name = "leaveListenerExecutor")
|
||||
public TaskExecutor leaveListenerExecutor() {
|
||||
return setupExecutorFor("leaveListener");
|
||||
}
|
||||
|
||||
@Bean(name = "messageReceivedExecutor")
|
||||
public TaskExecutor messageReceivedExecutor() {
|
||||
return setupExecutorFor("messageReceivedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "messageDeletedExecutor")
|
||||
public TaskExecutor messageDeletedExecutor() {
|
||||
return setupExecutorFor("messageReceivedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "messageEmbeddedExecutor")
|
||||
public TaskExecutor messageEmbeddedExecutor() {
|
||||
return setupExecutorFor("messageEmbeddedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "messageUpdatedExecutor")
|
||||
public TaskExecutor messageUpdatedExecutor() {
|
||||
return setupExecutorFor("messageUpdatedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "privateMessageReceivedExecutor")
|
||||
public TaskExecutor privateMessageReceivedExecutor() {
|
||||
return setupExecutorFor("privateMessageReceivedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "emoteCreatedExecutor")
|
||||
public TaskExecutor emoteCreatedExecutor() {
|
||||
return setupExecutorFor("emoteCreatedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "emoteDeletedExecutor")
|
||||
public TaskExecutor emoteDeletedExecutor() {
|
||||
return setupExecutorFor("emoteDeletedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "emoteUpdatedExecutor")
|
||||
public TaskExecutor emoteUpdatedExecutor() {
|
||||
return setupExecutorFor("emoteUpdatedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "reactionAddedExecutor")
|
||||
public TaskExecutor reactionAddedExecutor() {
|
||||
return setupExecutorFor("reactionAddedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "reactionRemovedExecutor")
|
||||
public TaskExecutor reactionRemovedExecutor() {
|
||||
return setupExecutorFor("reactionRemovedListener");
|
||||
}
|
||||
|
||||
@Bean(name = "reactionClearedExecutor")
|
||||
public TaskExecutor reactionClearedExecutor() {
|
||||
return setupExecutorFor("reactionClearedListener");
|
||||
}
|
||||
|
||||
public ThreadPoolTaskExecutor setupExecutorFor(String listenerName) {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
Integer maxPoolSize = getPropertyValueInteger(listenerName, LISTENER_MAX_POOL_SIZE, defaultMaxPoolSize.toString());
|
||||
Integer corePoolSize = getPropertyValueInteger(listenerName, LISTENER_CORE_POOL_SIZE, defaultCorePoolSize.toString());
|
||||
Integer keepAliveSeconds = getPropertyValueInteger(listenerName, LISTENER_KEEP_ALIVE_SECONDS, defaultKeepAliveSeconds.toString());
|
||||
executor.setCorePoolSize(corePoolSize);
|
||||
executor.setMaxPoolSize(maxPoolSize);
|
||||
executor.setKeepAliveSeconds(keepAliveSeconds);
|
||||
executor.setThreadNamePrefix(listenerName + "-task-executor-thread");
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
public String getPropertyValue(String listenerName, String key, String defaultValue) {
|
||||
return environment.getProperty(LISTENER_PREFIX + listenerName + "." + key, defaultValue);
|
||||
}
|
||||
|
||||
public Integer getPropertyValueInteger(String listenerName, String key, String defaultValue) {
|
||||
return Integer.parseInt(getPropertyValue(listenerName, key, defaultValue));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteAddedEvent;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteRemovedEvent;
|
||||
import net.dv8tion.jda.api.events.emote.update.EmoteUpdateNameEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class EmoteListener extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private List<EmoteCreatedListener> createdListeners;
|
||||
|
||||
@Autowired
|
||||
private List<EmoteDeletedListener> deletedListeners;
|
||||
|
||||
@Autowired
|
||||
private List<EmoteUpdatedListener> updatedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private EmoteListener self;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onEmoteAdded(@NotNull EmoteAddedEvent event) {
|
||||
createdListeners.forEach(listener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeCreatedListener(listener, event.getEmote());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeCreatedListener(EmoteCreatedListener listener, Emote createDdEmote) {
|
||||
listener.emoteCreated(createDdEmote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmoteRemoved(@NotNull EmoteRemovedEvent event) {
|
||||
deletedListeners.forEach(listener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeDeletedListener(listener, event.getEmote());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeDeletedListener(EmoteDeletedListener listener, Emote createDdEmote) {
|
||||
listener.emoteDeleted(createDdEmote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEmoteUpdateName(@NotNull EmoteUpdateNameEvent event) {
|
||||
updatedListeners.forEach(emoteUpdatedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(emoteUpdatedListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(emoteUpdatedListener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeUpdatedListener(emoteUpdatedListener, event.getEmote(), event.getOldName(), event.getNewName());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeUpdatedListener(EmoteUpdatedListener listener, Emote updatedEmote, String oldName, String newName) {
|
||||
listener.emoteUpdated(updatedEmote, oldName, newName);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
createdListeners.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
deletedListeners.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
updatedListeners.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageReceivedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private List<MessageReceivedListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private List<PrivateMessageReceivedListener> privateMessageReceivedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired
|
||||
private MessageReceivedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
|
||||
messageCache.putMessageInCache(event.getMessage());
|
||||
listenerList.forEach(messageReceivedListener -> {
|
||||
try {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeIndividualGuildMessageReceivedListener(event, messageReceivedListener);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
exceptionService.reportExceptionToGuildMessageReceivedContext(e, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualGuildMessageReceivedListener(@Nonnull GuildMessageReceivedEvent event, MessageReceivedListener messageReceivedListener) {
|
||||
messageReceivedListener.execute(event.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrivateMessageReceived(@Nonnull PrivateMessageReceivedEvent event) {
|
||||
if(event.getAuthor().getId().equals(botService.getInstance().getSelfUser().getId())) {
|
||||
return;
|
||||
}
|
||||
privateMessageReceivedListeners.forEach(messageReceivedListener -> {
|
||||
try {
|
||||
self.executeIndividualPrivateMessageReceivedListener(event, messageReceivedListener);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
exceptionService.reportExceptionToPrivateMessageReceivedContext(e, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualPrivateMessageReceivedListener(@Nonnull PrivateMessageReceivedEvent event, PrivateMessageReceivedListener messageReceivedListener) {
|
||||
log.trace("Executing private message listener {} for member {}.", messageReceivedListener.getClass().getName(), event.getAuthor().getId());
|
||||
messageReceivedListener.execute(event.getMessage());
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
privateMessageReceivedListeners.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
}
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveAllEvent;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ReactionUpdatedListener extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private List<ReactedAddedListener> addedListenerList;
|
||||
|
||||
@Autowired
|
||||
private List<ReactionClearedListener> clearedListenerList;
|
||||
|
||||
@Autowired
|
||||
private List<ReactedRemovedListener> reactionRemovedListeners;
|
||||
|
||||
@Autowired
|
||||
private ReactionUpdatedListener self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionAdd(@Nonnull GuildMessageReactionAddEvent event) {
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage ->
|
||||
messageCache.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction -> {
|
||||
self.callAddedListeners(event, cachedMessage, reaction);
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to handle add reaction to message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
})
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void addReactionIfNotThere(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting) {
|
||||
Optional<CachedReaction> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
emoteService.compareAEmote(reaction1.getEmote(), reaction.getEmote())
|
||||
).findAny();
|
||||
if(!existingReaction.isPresent()) {
|
||||
message.getReactions().add(reaction);
|
||||
} else {
|
||||
CachedReaction cachedReaction = existingReaction.get();
|
||||
Optional<Long> any = cachedReaction.getUserInServersIds().stream().filter(user -> user.equals(userReacting.getUserInServerId())).findAny();
|
||||
if(!any.isPresent()){
|
||||
cachedReaction.getUserInServersIds().add(userReacting.getUserInServerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeReactionIfThere(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting) {
|
||||
Optional<CachedReaction> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
emoteService.compareAEmote(reaction1.getEmote(), reaction.getEmote())
|
||||
).findAny();
|
||||
if(existingReaction.isPresent()) {
|
||||
CachedReaction cachedReaction = existingReaction.get();
|
||||
cachedReaction.getUserInServersIds().removeIf(user -> user.equals(userReacting.getUserInServerId()));
|
||||
message.getReactions().removeIf(reaction1 -> reaction1.getUserInServersIds().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReaction reaction) {
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
|
||||
addReactionIfNotThere(cachedMessage, reaction, userInAServer);
|
||||
addedListenerList.forEach(reactedAddedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactedAddedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividiualReactionAddedListener(event, cachedMessage, userInAServer, reactedAddedListener);
|
||||
} catch (Exception e) {
|
||||
log.warn(String.format("Failed to execute reaction added listener %s.", reactedAddedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividiualReactionAddedListener(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, AUserInAServer userInAServer, ReactedAddedListener reactedAddedListener) {
|
||||
reactedAddedListener.executeReactionAdded(cachedMessage, event, userInAServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemove(@Nonnull GuildMessageReactionRemoveEvent event) {
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
messageCache.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction ->
|
||||
self.callRemoveListeners(event, cachedMessage, reaction)
|
||||
) .exceptionally(throwable -> {
|
||||
log.error("Failed to retrieve cached reaction for message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callRemoveListeners(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, CachedReaction reaction) {
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadUser(event.getGuild().getIdLong(), event.getUserIdLong());
|
||||
removeReactionIfThere(cachedMessage, reaction, userInAServer);
|
||||
reactionRemovedListeners.forEach(reactionRemovedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividualReactionRemovedListener(event, cachedMessage, userInAServer, reactionRemovedListener);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction removed listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualReactionRemovedListener(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, AUserInAServer userInAServer, ReactedRemovedListener reactionRemovedListener) {
|
||||
reactionRemovedListener.executeReactionRemoved(cachedMessage, event, userInAServer);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callClearListeners(@Nonnull GuildMessageReactionRemoveAllEvent event, CachedMessage cachedMessage) {
|
||||
clearedListenerList.forEach(reactionRemovedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reactionRemovedListener.executeReactionCleared(cachedMessage);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction clear listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemoveAll(@Nonnull GuildMessageReactionRemoveAllEvent event) {
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
cachedMessage.getReactions().clear();
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
self.callClearListeners(event, cachedMessage);
|
||||
}) .exceptionally(throwable -> {
|
||||
log.error("Message retrieval from cache failed for message {}", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
reactionRemovedListeners.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
addedListenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
clearedListenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.service.CacheEntityService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteAddedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AsyncEmoteCreatedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncEmoteCreatedListener> createdListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private AsyncEmoteCreatedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("emoteCreatedExecutor")
|
||||
private TaskExecutor emoteCreatedExecutor;
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onEmoteAdded(@NotNull EmoteAddedEvent event) {
|
||||
if(createdListeners == null) return;
|
||||
CachedEmote cachedEmote = cacheEntityService.getCachedEmoteFromEmote(event.getEmote(), event.getGuild());
|
||||
createdListeners.forEach(emoteUpdatedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeCreatedListener(emoteUpdatedListener, cachedEmote, event.getGuild().getIdLong())
|
||||
, emoteCreatedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async join listener {} failed with exception.", emoteUpdatedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeCreatedListener(AsyncEmoteCreatedListener listener, CachedEmote createDdEmote, Long serverId) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, serverId)) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, serverId)) {
|
||||
return;
|
||||
}
|
||||
listener.emoteCreated(createDdEmote);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.service.CacheEntityService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteRemovedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AsyncEmoteDeletedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncEmoteDeletedListener> deletedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private AsyncEmoteDeletedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("emoteDeletedExecutor")
|
||||
private TaskExecutor emoteCreatedExecutor;
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Override
|
||||
public void onEmoteRemoved(@NotNull EmoteRemovedEvent event) {
|
||||
if(deletedListeners == null) return;
|
||||
CachedEmote cachedEmote = cacheEntityService.getCachedEmoteFromEmote(event.getEmote(), event.getGuild());
|
||||
|
||||
deletedListeners.forEach(emoteUpdatedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeDeletedListener(emoteUpdatedListener, cachedEmote, event.getGuild().getIdLong())
|
||||
, emoteCreatedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async join listener {} failed with exception.", emoteUpdatedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeDeletedListener(AsyncEmoteDeletedListener listener, CachedEmote deletedEmote, Long serverId) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, serverId)) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, serverId)) {
|
||||
return;
|
||||
}
|
||||
listener.emoteDeleted(deletedEmote);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.service.CacheEntityService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.emote.update.EmoteUpdateNameEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AsyncEmoteUpdatedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncEmoteUpdatedListener> updatedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private AsyncEmoteUpdatedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("emoteUpdatedExecutor")
|
||||
private TaskExecutor emoteUpdatedExecutor;
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Override
|
||||
public void onEmoteUpdateName(@NotNull EmoteUpdateNameEvent event) {
|
||||
if(updatedListeners == null) return;
|
||||
CachedEmote cachedEmote = cacheEntityService.getCachedEmoteFromEmote(event.getEmote(), event.getGuild());
|
||||
updatedListeners.forEach(emoteUpdatedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeUpdatedListener(emoteUpdatedListener, cachedEmote, event.getOldName(), event.getNewName(), event.getGuild().getIdLong())
|
||||
, emoteUpdatedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async join listener {} failed with exception.", emoteUpdatedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeUpdatedListener(AsyncEmoteUpdatedListener listener, CachedEmote updatedEmote, String oldName, String newName, Long serverId) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, serverId)) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, serverId)) {
|
||||
return;
|
||||
}
|
||||
listener.emoteUpdated(updatedEmote, oldName, newName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncJoinListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncJoinListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private AsyncJoinListenerBean self;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("joinListenerExecutor")
|
||||
private TaskExecutor joinListenerExecutor;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) {
|
||||
if(listenerList == null) return;
|
||||
listenerList.forEach(joinListener -> {
|
||||
ServerUser serverUser = ServerUser
|
||||
.builder()
|
||||
.serverId(event.getGuild().getIdLong())
|
||||
.userId(event.getUser().getIdLong())
|
||||
.build();
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualJoinListener(joinListener, serverUser)
|
||||
, joinListenerExecutor).exceptionally(throwable -> {
|
||||
log.error("Async join listener {} failed with exception.", joinListener, throwable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualJoinListener(AsyncJoinListener joinListener, ServerUser serverUser) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(joinListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, serverUser.getServerId())) {
|
||||
return;
|
||||
}
|
||||
log.trace("Executing async join listener {} for user {} in server {}.", joinListener, serverUser.getServerId(), serverUser.getUserId());
|
||||
try {
|
||||
joinListener.execute(serverUser);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} failed with exception:", joinListener.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncLeaveListenerBean extends ListenerAdapter {
|
||||
@Autowired(required = false)
|
||||
private List<AsyncLeaveListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("leaveListenerExecutor")
|
||||
private TaskExecutor leaveListenerExecutor;
|
||||
|
||||
@Autowired
|
||||
private AsyncLeaveListenerBean self;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMemberRemove(@Nonnull GuildMemberRemoveEvent event) {
|
||||
if(listenerList == null) return;
|
||||
listenerList.forEach(leaveListener -> {
|
||||
ServerUser serverUser = ServerUser
|
||||
.builder()
|
||||
.userId(event.getUser().getIdLong())
|
||||
.serverId(event.getGuild().getIdLong())
|
||||
.build();
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualLeaveListener(serverUser, leaveListener)
|
||||
, leaveListenerExecutor).exceptionally(throwable -> {
|
||||
log.error("Async leave listener {} threw exception.", leaveListener, throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualLeaveListener(ServerUser user, AsyncLeaveListener leaveListener) {
|
||||
log.trace("Executing leave listener {} for member {} in guild {}.", leaveListener.getClass().getName(), user.getUserId(), user.getServerId());
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(leaveListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, user.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
leaveListener.execute(user);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error("Listener {} failed with exception:", leaveListener.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncMessageDeletedListenerBean extends ListenerAdapter {
|
||||
@Autowired(required = false)
|
||||
private List<AsyncMessageDeletedListener> listener;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private AsyncMessageDeletedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("messageDeletedExecutor")
|
||||
private TaskExecutor messageDeletedListenerExecutor;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) {
|
||||
if(listener == null) return;
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.executeListener(cachedMessage);
|
||||
messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong())
|
||||
.thenAccept(cachedMessageConsumer)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executeListener(CachedMessage cachedMessage) {
|
||||
listener.forEach(messageDeletedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualMessageDeletedListener(cachedMessage, messageDeletedListener)
|
||||
, messageDeletedListenerExecutor).exceptionally(throwable -> {
|
||||
log.error("Async message deleted {} failed with exception.", messageDeletedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualMessageDeletedListener(CachedMessage cachedMessage, AsyncMessageDeletedListener messageDeletedListener) {
|
||||
log.trace("Executing message deleted listener {} for message {} in guild {}.", messageDeletedListener.getClass().getName(), cachedMessage.getMessageId(), cachedMessage.getMessageId());
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageDeletedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
messageDeletedListener.execute(cachedMessage);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error("Listener {} failed with exception:", messageDeletedListener.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageEmbedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncMessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncMessageEmbeddedListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("messageEmbeddedExecutor")
|
||||
private TaskExecutor messageEmbeddedListener;
|
||||
|
||||
@Autowired
|
||||
private AsyncMessageEmbeddedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onGuildMessageEmbed(@NotNull GuildMessageEmbedEvent event) {
|
||||
if(listenerList == null) return;
|
||||
GuildMessageEmbedEventModel model = buildModel(event);
|
||||
listenerList.forEach(messageReceivedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualGuildMessageReceivedListener(model, messageReceivedListener)
|
||||
, messageEmbeddedListener).exceptionally(throwable -> {
|
||||
log.error("Async message embedded listener {} failed with exception.", messageReceivedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private GuildMessageEmbedEventModel buildModel(GuildMessageEmbedEvent event) {
|
||||
return GuildMessageEmbedEventModel
|
||||
.builder()
|
||||
.channelId(event.getChannel().getIdLong())
|
||||
.serverId(event.getGuild().getIdLong())
|
||||
.embeds(event.getMessageEmbeds())
|
||||
.messageId(event.getMessageIdLong())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
|
||||
public void executeIndividualGuildMessageReceivedListener(GuildMessageEmbedEventModel model, AsyncMessageEmbeddedListener messageReceivedListener) {
|
||||
try {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, model.getServerId())) {
|
||||
return;
|
||||
}
|
||||
messageReceivedListener.execute(model);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncMessageReceivedListenerBean extends ListenerAdapter {
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncMessageReceivedListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("messageReceivedExecutor")
|
||||
private TaskExecutor messageReceivedExecutor;
|
||||
|
||||
@Autowired
|
||||
private AsyncMessageReceivedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
|
||||
if(listenerList == null) return;
|
||||
messageCache.putMessageInCache(event.getMessage()).thenAccept(message -> {
|
||||
for (AsyncMessageReceivedListener messageReceivedListener : listenerList) {
|
||||
CompletableFuture.runAsync(() -> self.executeIndividualGuildMessageReceivedListener(message, messageReceivedListener), messageReceivedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async message received listener {} failed.", messageReceivedListener, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualGuildMessageReceivedListener(CachedMessage cachedMessage, AsyncMessageReceivedListener messageReceivedListener) {
|
||||
try {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
messageReceivedListener.execute(cachedMessage);
|
||||
} catch (Exception e) {
|
||||
log.error("Async listener {} had exception when executing.", messageReceivedListener, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncMessageUpdatedListenerBean extends ListenerAdapter {
|
||||
@Autowired(required = false)
|
||||
private List<AsyncMessageTextUpdatedListener> listener;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private AsyncMessageUpdatedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("messageUpdatedExecutor")
|
||||
private TaskExecutor messageUpdatedExecutor;
|
||||
|
||||
@Override
|
||||
public void onGuildMessageUpdate(GuildMessageUpdateEvent event) {
|
||||
if(listener == null) return;
|
||||
Message message = event.getMessage();
|
||||
messageCache.getMessageFromCache(message.getGuild().getIdLong(), message.getTextChannel().getIdLong(), event.getMessageIdLong())
|
||||
.thenAcceptBoth(messageCache.putMessageInCache(message), (oldCache, newCache) -> self.executeListener(newCache, oldCache))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessage().getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executeListener(CachedMessage updatedMessage, CachedMessage oldMessage) {
|
||||
listener.forEach(messageTextUpdatedListener ->
|
||||
CompletableFuture
|
||||
.runAsync(() -> self.executeIndividualMessageUpdatedListener(updatedMessage, oldMessage, messageTextUpdatedListener), messageUpdatedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async message receiver listener {} failed.", messageTextUpdatedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualMessageUpdatedListener(CachedMessage updatedMessage, CachedMessage cachedMessage, AsyncMessageTextUpdatedListener messageTextUpdatedListener) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageTextUpdatedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
messageTextUpdatedListener.execute(cachedMessage, updatedMessage);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.error(String.format("Failed to execute listener. %s", messageTextUpdatedListener.getClass().getName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.CacheEntityService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncPrivateMessageReceivedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncPrivateMessageReceivedListener> privateMessageReceivedListeners;
|
||||
|
||||
@Autowired
|
||||
private AsyncPrivateMessageReceivedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("privateMessageReceivedExecutor")
|
||||
private TaskExecutor privateMessageReceivedExecutor;
|
||||
|
||||
@Override
|
||||
public void onPrivateMessageReceived(@Nonnull PrivateMessageReceivedEvent event) {
|
||||
if(privateMessageReceivedListeners == null) return;
|
||||
if(event.getAuthor().getId().equals(botService.getInstance().getSelfUser().getId())) {
|
||||
return;
|
||||
}
|
||||
cacheEntityService.buildCachedMessageFromMessage(event.getMessage()).thenAccept(cachedMessage ->
|
||||
privateMessageReceivedListeners.forEach(messageReceivedListener -> {
|
||||
try {
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualPrivateMessageReceivedListener(cachedMessage, messageReceivedListener)
|
||||
, privateMessageReceivedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async private message receiver listener {} failed.", messageReceivedListener, throwable);
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("Private message received {} had exception when executing.", messageReceivedListener, e);
|
||||
exceptionService.reportExceptionToPrivateMessageReceivedContext(e, event);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualPrivateMessageReceivedListener(CachedMessage cachedMessage, AsyncPrivateMessageReceivedListener messageReceivedListener) {
|
||||
log.trace("Executing private message listener {} for member {}.", messageReceivedListener.getClass().getName(), cachedMessage.getAuthor().getAuthorId());
|
||||
messageReceivedListener.execute(cachedMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncReactionAddedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncReactionAddedListener> addedListenerList;
|
||||
|
||||
@Autowired
|
||||
private AsyncReactionAddedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("reactionAddedExecutor")
|
||||
private TaskExecutor reactionAddedTaskExecutor;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionAdd(@Nonnull GuildMessageReactionAddEvent event) {
|
||||
if(addedListenerList == null) return;
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage ->
|
||||
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction ->
|
||||
self.callAddedListeners(event, cachedMessage, reaction)
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Failed to handle add reaction to message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
})
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void addReactionIfNotThere(CachedMessage message, CachedReactions reaction, ServerUser userReacting) {
|
||||
Optional<CachedReactions> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
reaction1.getEmote().equals(reaction.getEmote())
|
||||
).findAny();
|
||||
if(!existingReaction.isPresent()) {
|
||||
message.getReactions().add(reaction);
|
||||
} else {
|
||||
CachedReactions cachedReaction = existingReaction.get();
|
||||
Optional<ServerUser> any = cachedReaction.getUsers().stream().filter(user -> user.getUserId().equals(userReacting.getUserId()) && user.getServerId().equals(userReacting.getServerId())).findAny();
|
||||
if(!any.isPresent()){
|
||||
cachedReaction.getUsers().add(userReacting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction) {
|
||||
ServerUser serverUser = ServerUser.builder().serverId(event.getGuild().getIdLong()).userId(event.getUserIdLong()).build();
|
||||
addReactionIfNotThere(cachedMessage, reaction, serverUser);
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
addedListenerList.forEach(reactedAddedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualReactionAddedListener(reaction, cachedMessage, serverUser, reactedAddedListener)
|
||||
, reactionAddedTaskExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async reaction added listener {} failed with exception.", reactedAddedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualReactionAddedListener(@Nonnull CachedReactions reaction, CachedMessage cachedMessage, ServerUser serverUser, AsyncReactionAddedListener reactedAddedListener) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactedAddedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, serverUser.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reactedAddedListener.executeReactionAdded(cachedMessage, reaction, serverUser);
|
||||
} catch (Exception e) {
|
||||
log.warn(String.format("Failed to execute reaction added listener %s.", reactedAddedListener.getClass().getName()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveAllEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncReactionClearedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncReactionClearedListener> clearedListenerList;
|
||||
|
||||
@Autowired
|
||||
private AsyncReactionClearedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("reactionClearedExecutor")
|
||||
private TaskExecutor reactionClearedExecutor;
|
||||
|
||||
@Transactional
|
||||
public void callClearListeners(CachedMessage cachedMessage) {
|
||||
if(clearedListenerList == null) return;
|
||||
clearedListenerList.forEach(reactionRemovedListener ->
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.callConcreteListener(cachedMessage, reactionRemovedListener)
|
||||
, reactionClearedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async reaction cleared listener {} failed with exception.", reactionRemovedListener, throwable);
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void callConcreteListener(CachedMessage cachedMessage, AsyncReactionClearedListener reactionRemovedListener) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reactionRemovedListener.executeReactionCleared(cachedMessage);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction clear listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemoveAll(@Nonnull GuildMessageReactionRemoveAllEvent event) {
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
cachedMessage.getReactions().clear();
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
self.callClearListeners(cachedMessage);
|
||||
}) .exceptionally(throwable -> {
|
||||
log.error("Message retrieval from cache failed for message {}", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AsyncReactionRemovedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<AsyncReactionRemovedListener> reactionRemovedListeners;
|
||||
|
||||
@Autowired
|
||||
private AsyncReactionRemovedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("reactionRemovedExecutor")
|
||||
private TaskExecutor reactionRemovedExecutor;
|
||||
|
||||
private void removeReactionIfThere(CachedMessage message, CachedReactions reaction, ServerUser serverUser) {
|
||||
Optional<CachedReactions> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
reaction1.getEmote().equals(reaction.getEmote())
|
||||
).findAny();
|
||||
if(existingReaction.isPresent()) {
|
||||
CachedReactions cachedReaction = existingReaction.get();
|
||||
cachedReaction.getUsers().removeIf(user -> user.getUserId().equals(serverUser.getUserId()) && user.getServerId().equals(serverUser.getServerId()));
|
||||
message.getReactions().removeIf(reaction1 -> reaction1.getUsers().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemove(@Nonnull GuildMessageReactionRemoveEvent event) {
|
||||
if(reactionRemovedListeners == null) return;
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction ->
|
||||
self.callRemoveListeners(event, cachedMessage, reaction)
|
||||
) .exceptionally(throwable -> {
|
||||
log.error("Failed to retrieve cached reaction for message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callRemoveListeners(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, CachedReactions reaction) {
|
||||
ServerUser serverUser = ServerUser.builder().serverId(cachedMessage.getServerId()).userId(event.getUserIdLong()).build();
|
||||
removeReactionIfThere(cachedMessage, reaction, serverUser);
|
||||
reactionRemovedListeners.forEach(reactionRemovedListener -> {
|
||||
try {
|
||||
CompletableFuture.runAsync(() ->
|
||||
self.executeIndividualReactionRemovedListener(reaction, cachedMessage, serverUser, reactionRemovedListener)
|
||||
, reactionRemovedExecutor)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Async reaction removed listener {} failed with exception.", reactionRemovedListener, throwable);
|
||||
return null;
|
||||
});
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction removed listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualReactionRemovedListener(@Nonnull CachedReactions reaction, CachedMessage cachedMessage, ServerUser userRemoving, AsyncReactionRemovedListener reactionRemovedListener) {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, cachedMessage.getServerId())) {
|
||||
return;
|
||||
}
|
||||
reactionRemovedListener.executeReactionRemoved(cachedMessage, reaction, userRemoving);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener.entity;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ChannelGroupCreatedListenerManager {
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<ChannelGroupCreatedListener> listener;
|
||||
|
||||
@Autowired
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener.entity;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ChannelGroupDeletedListenerManager {
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<ChannelGroupDeletedListener> listener;
|
||||
|
||||
public void executeListener(AChannelGroup createdGroup){
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.CommandManager;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AFeature;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelType;
|
||||
@@ -25,6 +25,8 @@ public class ChannelListener extends ListenerAdapter {
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
// TODO move this to a separate sync listener, which implements a a generic channel listener, in order to provide
|
||||
// the channel listener for other implementations
|
||||
@Override
|
||||
@Transactional
|
||||
public void onTextChannelDelete(@Nonnull TextChannelDeleteEvent event) {
|
||||
@@ -0,0 +1,67 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteAddedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class EmoteCreatedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EmoteCreatedListener> createdListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private EmoteCreatedListenerBean self;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onEmoteAdded(@NotNull EmoteAddedEvent event) {
|
||||
if(createdListeners == null) return;
|
||||
createdListeners.forEach(listener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeCreatedListener(listener, event.getEmote());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeCreatedListener(EmoteCreatedListener listener, Emote createDdEmote) {
|
||||
listener.emoteCreated(createDdEmote);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(createdListeners);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.events.emote.EmoteRemovedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class EmoteDeletedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EmoteDeletedListener> deletedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private EmoteDeletedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onEmoteRemoved(@NotNull EmoteRemovedEvent event) {
|
||||
if(deletedListeners == null) return;
|
||||
deletedListeners.forEach(listener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(listener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(listener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeDeletedListener(listener, event.getEmote());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeDeletedListener(EmoteDeletedListener listener, Emote createDdEmote) {
|
||||
listener.emoteDeleted(createDdEmote);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(deletedListeners);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.events.emote.update.EmoteUpdateNameEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class EmoteUpdatedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<EmoteUpdatedListener> updatedListeners;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private EmoteUpdatedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onEmoteUpdateName(@NotNull EmoteUpdateNameEvent event) {
|
||||
if(updatedListeners == null) return;
|
||||
updatedListeners.forEach(emoteUpdatedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(emoteUpdatedListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
if(!featureModeService.necessaryFeatureModesMet(emoteUpdatedListener, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
self.executeUpdatedListener(emoteUpdatedListener, event.getEmote(), event.getOldName(), event.getNewName());
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeUpdatedListener(EmoteUpdatedListener listener, Emote updatedEmote, String oldName, String newName) {
|
||||
listener.emoteUpdated(updatedEmote, oldName, newName);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(updatedListeners);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
@@ -15,15 +16,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class JoinListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<JoinListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
@@ -41,6 +40,7 @@ public class JoinListenerBean extends ListenerAdapter {
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMemberJoin(@Nonnull GuildMemberJoinEvent event) {
|
||||
if(listenerList == null) return;
|
||||
listenerList.forEach(joinListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(joinListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
@@ -63,6 +63,6 @@ public class JoinListenerBean extends ListenerAdapter {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
BeanUtils.sortPrioritizedListeners(listenerList);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
@@ -14,14 +15,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LeaveListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<LeaveListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
@@ -36,6 +36,7 @@ public class LeaveListenerBean extends ListenerAdapter {
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMemberRemove(@Nonnull GuildMemberRemoveEvent event) {
|
||||
if(listenerList == null) return;
|
||||
listenerList.forEach(leaveListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(leaveListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
@@ -57,6 +58,6 @@ public class LeaveListenerBean extends ListenerAdapter {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
BeanUtils.sortPrioritizedListeners(listenerList);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
@@ -13,6 +13,7 @@ import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
@@ -23,14 +24,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<MessageDeletedListener> listener;
|
||||
|
||||
@Autowired
|
||||
@@ -60,6 +60,7 @@ public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageDelete(@Nonnull GuildMessageDeleteEvent event) {
|
||||
if(listener == null) return;
|
||||
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.executeListener(cachedMessage);
|
||||
messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong())
|
||||
.thenAccept(cachedMessageConsumer)
|
||||
@@ -76,14 +77,14 @@ public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
.builder()
|
||||
.guild(serverManagementService.loadOrCreate(cachedMessage.getServerId()))
|
||||
.channel(channelManagementService.loadChannel(cachedMessage.getChannelId()))
|
||||
.aUserInAServer(userInServerManagementService.loadUser(cachedMessage.getServerId(), cachedMessage.getAuthorId()))
|
||||
.aUserInAServer(userInServerManagementService.loadUser(cachedMessage.getServerId(), cachedMessage.getAuthor().getAuthorId()))
|
||||
.build();
|
||||
botService.getMemberInServerAsync(cachedMessage.getServerId(), cachedMessage.getAuthorId()).thenAccept(member -> {
|
||||
botService.getMemberInServerAsync(cachedMessage.getServerId(), cachedMessage.getAuthor().getAuthorId()).thenAccept(member -> {
|
||||
GuildChannelMember authorMember = GuildChannelMember
|
||||
.builder()
|
||||
.guild(botService.getGuildById(cachedMessage.getServerId()))
|
||||
.textChannel(botService.getTextChannelFromServerOptional(cachedMessage.getServerId(), cachedMessage.getChannelId()).orElseThrow(() -> new ChannelNotInGuildException(cachedMessage.getChannelId())))
|
||||
.member(botService.getMemberInServer(cachedMessage.getServerId(), cachedMessage.getAuthorId()))
|
||||
.member(botService.getMemberInServer(cachedMessage.getServerId(), cachedMessage.getAuthor().getAuthorId()))
|
||||
.build();
|
||||
listener.forEach(messageDeletedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageDeletedListener.getFeature());
|
||||
@@ -111,6 +112,6 @@ public class MessageDeletedListenerBean extends ListenerAdapter {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listener.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
BeanUtils.sortPrioritizedListeners(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
@@ -7,6 +7,7 @@ import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageEmbedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
@@ -18,7 +19,6 @@ import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@@ -28,7 +28,7 @@ public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<MessageEmbeddedListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
@@ -48,6 +48,7 @@ public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void onGuildMessageEmbed(@NotNull GuildMessageEmbedEvent event) {
|
||||
if(listenerList == null) return;
|
||||
GuildMessageEmbedEventModel model = buildModel(event);
|
||||
listenerList.forEach(messageReceivedListener -> {
|
||||
try {
|
||||
@@ -58,7 +59,6 @@ public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
self.executeIndividualGuildMessageReceivedListener(model, messageReceivedListener);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
// exceptionService.reportExceptionToGuildMessageReceivedContext(e, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -66,7 +66,8 @@ public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
private GuildMessageEmbedEventModel buildModel(GuildMessageEmbedEvent event) {
|
||||
return GuildMessageEmbedEventModel
|
||||
.builder()
|
||||
.channel(event.getChannel())
|
||||
.channelId(event.getChannel().getIdLong())
|
||||
.serverId(event.getGuild().getIdLong())
|
||||
.embeds(event.getMessageEmbeds())
|
||||
.messageId(event.getMessageIdLong())
|
||||
.build();
|
||||
@@ -79,6 +80,6 @@ public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listenerList.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
BeanUtils.sortPrioritizedListeners(listenerList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageReceivedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<MessageReceivedListener> listenerList;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired
|
||||
private MessageReceivedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event) {
|
||||
messageCache.putMessageInCache(event.getMessage());
|
||||
if(listenerList == null) return;
|
||||
for (MessageReceivedListener messageReceivedListener : listenerList) {
|
||||
try {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(messageReceivedListener.getFeature());
|
||||
if (!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
continue;
|
||||
}
|
||||
MessageReceivedListenerResult result = self.executeIndividualGuildMessageReceivedListener(event, messageReceivedListener);
|
||||
if (messageReceivedListener.shouldConsume(event, result)) {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
exceptionService.reportExceptionToGuildMessageReceivedContext(e, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public MessageReceivedListenerResult executeIndividualGuildMessageReceivedListener(@Nonnull GuildMessageReceivedEvent event, MessageReceivedListener messageReceivedListener) {
|
||||
return messageReceivedListener.execute(event.getMessage());
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(listenerList);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent;
|
||||
@@ -17,21 +18,20 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageUpdatedListener extends ListenerAdapter {
|
||||
public class MessageUpdatedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<MessageTextUpdatedListener> listener;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private MessageUpdatedListener self;
|
||||
private MessageUpdatedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
@@ -41,6 +41,7 @@ public class MessageUpdatedListener extends ListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void onGuildMessageUpdate(@Nonnull GuildMessageUpdateEvent event) {
|
||||
if(listener == null) return;
|
||||
Message message = event.getMessage();
|
||||
messageCache.getMessageFromCache(message.getGuild().getIdLong(), message.getTextChannel().getIdLong(), event.getMessageIdLong()).thenAccept(cachedMessage -> {
|
||||
self.executeListener(message, cachedMessage);
|
||||
@@ -74,6 +75,6 @@ public class MessageUpdatedListener extends ListenerAdapter {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
listener.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
BeanUtils.sortPrioritizedListeners(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class PrivateMessageReceivedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private ExceptionService exceptionService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<PrivateMessageReceivedListener> privateMessageReceivedListeners;
|
||||
|
||||
@Autowired
|
||||
private PrivateMessageReceivedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onPrivateMessageReceived(@Nonnull PrivateMessageReceivedEvent event) {
|
||||
if(privateMessageReceivedListeners == null) return;
|
||||
if(event.getAuthor().getId().equals(botService.getInstance().getSelfUser().getId())) {
|
||||
return;
|
||||
}
|
||||
privateMessageReceivedListeners.forEach(messageReceivedListener -> {
|
||||
try {
|
||||
self.executeIndividualPrivateMessageReceivedListener(event, messageReceivedListener);
|
||||
} catch (Exception e) {
|
||||
log.error("Listener {} had exception when executing.", messageReceivedListener, e);
|
||||
exceptionService.reportExceptionToPrivateMessageReceivedContext(e, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualPrivateMessageReceivedListener(@Nonnull PrivateMessageReceivedEvent event, PrivateMessageReceivedListener messageReceivedListener) {
|
||||
// no feature flag check, because we are in no server context
|
||||
log.trace("Executing private message listener {} for member {}.", messageReceivedListener.getClass().getName(), event.getAuthor().getId());
|
||||
messageReceivedListener.execute(event.getMessage());
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(privateMessageReceivedListeners);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ReactionAddedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<ReactionAddedListener> addedListenerList;
|
||||
|
||||
@Autowired
|
||||
private ReactionAddedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionAdd(@Nonnull GuildMessageReactionAddEvent event) {
|
||||
if(addedListenerList == null) return;
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage ->
|
||||
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction -> {
|
||||
self.callAddedListeners(event, cachedMessage, reaction);
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to handle add reaction to message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
})
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void addReactionIfNotThere(CachedMessage message, CachedReactions reaction, ServerUser userReacting) {
|
||||
Optional<CachedReactions> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
reaction1.getEmote().equals(reaction.getEmote())
|
||||
).findAny();
|
||||
if(!existingReaction.isPresent()) {
|
||||
message.getReactions().add(reaction);
|
||||
} else {
|
||||
CachedReactions cachedReaction = existingReaction.get();
|
||||
Optional<ServerUser> any = cachedReaction.getUsers().stream().filter(user -> user.getServerId().equals(userReacting.getServerId()) && user.getUserId().equals(userReacting.getUserId())).findAny();
|
||||
if(!any.isPresent()){
|
||||
cachedReaction.getUsers().add(userReacting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction) {
|
||||
ServerUser serverUser = ServerUser.builder().serverId(cachedMessage.getServerId()).userId(event.getUserIdLong()).build();
|
||||
addReactionIfNotThere(cachedMessage, reaction, serverUser);
|
||||
addedListenerList.forEach(reactedAddedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactedAddedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividualReactionAddedListener(event, cachedMessage, serverUser, reactedAddedListener);
|
||||
} catch (Exception e) {
|
||||
log.warn(String.format("Failed to execute reaction added listener %s.", reactedAddedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualReactionAddedListener(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, ServerUser serverUser, ReactionAddedListener reactedAddedListener) {
|
||||
reactedAddedListener.executeReactionAdded(cachedMessage, event, serverUser);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(addedListenerList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveAllEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ReactionClearedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<ReactionClearedListener> clearedListenerList;
|
||||
|
||||
@Autowired
|
||||
private ReactionClearedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void callClearListeners(@Nonnull GuildMessageReactionRemoveAllEvent event, CachedMessage cachedMessage) {
|
||||
if(clearedListenerList == null) return;
|
||||
clearedListenerList.forEach(reactionRemovedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
reactionRemovedListener.executeReactionCleared(cachedMessage);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction clear listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemoveAll(@Nonnull GuildMessageReactionRemoveAllEvent event) {
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
cachedMessage.getReactions().clear();
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
self.callClearListeners(event, cachedMessage);
|
||||
}) .exceptionally(throwable -> {
|
||||
log.error("Message retrieval from cache failed for message {}", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(clearedListenerList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
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 javax.annotation.Nonnull;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ReactionRemovedListenerBean extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
private MessageCache messageCache;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<ReactionRemovedListener> reactionRemovedListeners;
|
||||
|
||||
@Autowired
|
||||
private ReactionRemovedListenerBean self;
|
||||
|
||||
@Autowired
|
||||
private FeatureConfigService featureConfigService;
|
||||
|
||||
@Autowired
|
||||
private FeatureFlagService featureFlagService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
private void removeReactionIfThere(CachedMessage message, CachedReactions reaction, ServerUser userReacting) {
|
||||
Optional<CachedReactions> existingReaction = message.getReactions().stream().filter(reaction1 ->
|
||||
reaction1.getEmote().equals(reaction.getEmote())
|
||||
).findAny();
|
||||
if(existingReaction.isPresent()) {
|
||||
CachedReactions cachedReaction = existingReaction.get();
|
||||
cachedReaction.getUsers().removeIf(user -> user.getUserId().equals(userReacting.getUserId()) && user.getServerId().equals(userReacting.getServerId()));
|
||||
message.getReactions().removeIf(reaction1 -> reaction1.getUsers().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildMessageReactionRemove(@Nonnull GuildMessageReactionRemoveEvent event) {
|
||||
if(reactionRemovedListeners == null) return;
|
||||
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
|
||||
return;
|
||||
}
|
||||
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
|
||||
asyncMessageFromCache.thenAccept(cachedMessage -> {
|
||||
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction ->
|
||||
self.callRemoveListeners(event, cachedMessage, reaction)
|
||||
) .exceptionally(throwable -> {
|
||||
log.error("Failed to retrieve cached reaction for message {} ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
messageCache.putMessageInCache(cachedMessage);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void callRemoveListeners(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, CachedReactions reaction) {
|
||||
ServerUser serverUser = ServerUser.builder().serverId(event.getGuild().getIdLong()).userId(event.getUserIdLong()).build();
|
||||
removeReactionIfThere(cachedMessage, reaction, serverUser);
|
||||
reactionRemovedListeners.forEach(reactionRemovedListener -> {
|
||||
FeatureConfig feature = featureConfigService.getFeatureDisplayForFeature(reactionRemovedListener.getFeature());
|
||||
if(!featureFlagService.isFeatureEnabled(feature, event.getGuild().getIdLong())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
self.executeIndividualReactionRemovedListener(event, cachedMessage, serverUser, reactionRemovedListener);
|
||||
} catch (AbstractoRunTimeException e) {
|
||||
log.warn(String.format("Failed to execute reaction removed listener %s.", reactionRemovedListener.getClass().getName()), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void executeIndividualReactionRemovedListener(@Nonnull GuildMessageReactionRemoveEvent event, CachedMessage cachedMessage, ServerUser serverUser, ReactionRemovedListener reactionRemovedListener) {
|
||||
reactionRemovedListener.executeReactionRemoved(cachedMessage, event, serverUser);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
BeanUtils.sortPrioritizedListeners(reactionRemovedListeners);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.RoleService;
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -17,7 +18,7 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class ServerJoinListener extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private List<ServerConfigListener> configListeners;
|
||||
|
||||
@Autowired
|
||||
@@ -29,6 +30,7 @@ public class ServerJoinListener extends ListenerAdapter {
|
||||
@Override
|
||||
@Transactional
|
||||
public void onGuildJoin(@Nonnull GuildJoinEvent event) {
|
||||
if(configListeners == null) return;
|
||||
log.info("Joining guild {}, executing server config listener.", event.getGuild().getId());
|
||||
AServer server = serverManagementService.loadOrCreate(event.getGuild().getIdLong());
|
||||
configListeners.forEach(serverConfigListener -> self.executingIndividualServerConfigListener(server, serverConfigListener));
|
||||
@@ -17,6 +17,9 @@ public interface UserInServerRepository extends JpaRepository<AUserInAServer, Lo
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
Optional<AUserInAServer> findByServerReferenceAndUserReference(AServer serverId, AUser userId);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
Optional<AUserInAServer> findByServerReference_IdAndUserReference_Id(Long serverId, Long userId);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
boolean existsByServerReferenceAndUserReference(AServer server, AUser user);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.core.service;
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.GuildChannelMember;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
@@ -10,10 +11,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||
import net.dv8tion.jda.api.utils.MemberCachePolicy;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -95,6 +93,16 @@ public class BotServiceBean implements BotService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Member> retrieveMemberInServer(ServerUser serverUser) {
|
||||
return getMemberInServerAsync(serverUser.getServerId(), serverUser.getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<User> retrieveUserById(Long userId) {
|
||||
return instance.retrieveUserById(userId).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInGuild(AUserInAServer aUserInAServer) {
|
||||
Guild guildById = instance.getGuildById(aUserInAServer.getServerReference().getId());
|
||||
@@ -219,9 +227,19 @@ public class BotServiceBean implements BotService {
|
||||
return guildById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Guild> retrieveGuildById(Long serverId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member getBotInGuild(AServer server) {
|
||||
Guild guild = getGuildById(server.getId());
|
||||
return guild.getSelfMember();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<User> getUserViaId(Long userId) {
|
||||
return instance.retrieveUserById(userId).submit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.requests.restaction.pagination.ReactionPaginationAction;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CacheEntityServiceBean implements CacheEntityService {
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private CacheEntityServiceBean concreteSelf;
|
||||
|
||||
@Override
|
||||
public CachedEmote getCachedEmoteFromEmote(Emote emote, Guild guild) {
|
||||
return CachedEmote.builder()
|
||||
.emoteId(emote.getIdLong())
|
||||
.emoteName(emote.getName())
|
||||
.imageURL(emote.getImageUrl())
|
||||
.external(!emoteService.emoteIsFromGuild(emote, guild))
|
||||
.custom(true)
|
||||
.animated(emote.isAnimated())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedEmote getCachedEmoteFromEmote(MessageReaction.ReactionEmote emote, Guild guild) {
|
||||
if(emote.isEmoji()) {
|
||||
return CachedEmote.builder()
|
||||
.emoteName(emote.getName())
|
||||
.custom(false)
|
||||
.build();
|
||||
} else {
|
||||
return CachedEmote.builder()
|
||||
.emoteId(emote.getIdLong())
|
||||
.emoteName(emote.getName())
|
||||
.imageURL(emote.getEmote().getImageUrl())
|
||||
.external(emoteService.emoteIsFromGuild(emote.getEmote(), guild))
|
||||
.custom(true)
|
||||
.animated(emote.getEmote().isAnimated())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedAttachment getCachedAttachment(Message.Attachment attachment) {
|
||||
return CachedAttachment
|
||||
.builder()
|
||||
.fileName(attachment.getFileName())
|
||||
.height(attachment.getHeight())
|
||||
.proxyUrl(attachment.getProxyUrl())
|
||||
.size(attachment.getSize())
|
||||
.url(attachment.getUrl())
|
||||
.width(attachment.getWidth())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedEmbed getCachedEmbedFromEmbed(MessageEmbed embed) {
|
||||
CachedEmbed.CachedEmbedBuilder builder = CachedEmbed
|
||||
.builder();
|
||||
MessageEmbed.AuthorInfo author = embed.getAuthor();
|
||||
if(author != null) {
|
||||
builder.author(CachedEmbedAuthor.builder().avatar(author.getProxyIconUrl()).url(author.getUrl()).name(author.getName()).build());
|
||||
}
|
||||
List<MessageEmbed.Field> fields = embed.getFields();
|
||||
if(!fields.isEmpty()) {
|
||||
List<CachedEmbedField> cachedEmbedFields = new ArrayList<>();
|
||||
fields.forEach(field -> {
|
||||
CachedEmbedField build = CachedEmbedField
|
||||
.builder()
|
||||
.name(field.getName())
|
||||
.value(field.getValue())
|
||||
.inline(field.isInline())
|
||||
.build();
|
||||
cachedEmbedFields.add(build);
|
||||
});
|
||||
builder.fields(cachedEmbedFields);
|
||||
}
|
||||
MessageEmbed.ImageInfo image = embed.getImage();
|
||||
if(image != null) {
|
||||
builder.cachedImageInfo(buildCachedImage(image));
|
||||
}
|
||||
MessageEmbed.Thumbnail thumbnail = embed.getThumbnail();
|
||||
if(thumbnail != null) {
|
||||
builder.cachedThumbnail(buildCachedThumbnail(thumbnail));
|
||||
}
|
||||
Color color = embed.getColor();
|
||||
if(color != null) {
|
||||
CachedEmbedColor build = CachedEmbedColor
|
||||
.builder()
|
||||
.r(color.getRed())
|
||||
.g(color.getGreen())
|
||||
.b(color.getBlue())
|
||||
.build();
|
||||
builder.color(build);
|
||||
}
|
||||
builder.description(embed.getDescription());
|
||||
MessageEmbed.Footer footer = embed.getFooter();
|
||||
if(footer != null) {
|
||||
CachedEmbedFooter build = CachedEmbedFooter
|
||||
.builder()
|
||||
.icon(footer.getProxyIconUrl())
|
||||
.text(footer.getText())
|
||||
.build();
|
||||
builder.footer(build);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedThumbnail buildCachedThumbnail(MessageEmbed.Thumbnail thumbnail) {
|
||||
return CachedThumbnail
|
||||
.builder()
|
||||
.height(thumbnail.getHeight())
|
||||
.proxyUrl(thumbnail.getProxyUrl())
|
||||
.width(thumbnail.getWidth())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedImageInfo buildCachedImage(MessageEmbed.ImageInfo image) {
|
||||
return CachedImageInfo
|
||||
.builder()
|
||||
.height(image.getHeight())
|
||||
.proxyUrl(image.getProxyUrl())
|
||||
.url(image.getUrl())
|
||||
.width(image.getWidth())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CachedReactions> getCachedReactionFromReaction(MessageReaction reaction) {
|
||||
CompletableFuture<CachedReactions> future = new CompletableFuture<>();
|
||||
ReactionPaginationAction users = reaction.retrieveUsers();
|
||||
CachedReactions.CachedReactionsBuilder builder = CachedReactions.builder();
|
||||
|
||||
List<ServerUser> aUsers = new ArrayList<>();
|
||||
users.forEachAsync(user -> {
|
||||
concreteSelf.loadUser(reaction, aUsers, user);
|
||||
return false;
|
||||
}).thenAccept(o -> future.complete(builder.build()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to load reaction users.", throwable);
|
||||
return null;
|
||||
});
|
||||
builder.users(aUsers);
|
||||
builder.self(reaction.isSelf());
|
||||
builder.emote(getCachedEmoteFromEmote(reaction.getReactionEmote(), reaction.getGuild()));
|
||||
return future;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUser(MessageReaction reaction, List<ServerUser> aUsers, User user) {
|
||||
if(reaction.getGuild() != null) {
|
||||
aUsers.add(ServerUser.builder().userId(user.getIdLong()).serverId(reaction.getGuild().getIdLong()).build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CachedMessage> buildCachedMessageFromMessage(Message message) {
|
||||
CompletableFuture<CachedMessage> future = new CompletableFuture<>();
|
||||
List<CachedAttachment> attachments = new ArrayList<>();
|
||||
message.getAttachments().forEach(attachment ->
|
||||
attachments.add(getCachedAttachment(attachment))
|
||||
);
|
||||
List<CachedEmbed> embeds = new ArrayList<>();
|
||||
message.getEmbeds().forEach(embed ->
|
||||
embeds.add(getCachedEmbedFromEmbed(embed))
|
||||
);
|
||||
|
||||
List<CachedEmote> emotes = new ArrayList<>();
|
||||
if(message.isFromGuild()) {
|
||||
message.getEmotesBag().forEach(emote -> emotes.add(getCachedEmoteFromEmote(emote, message.getGuild())));
|
||||
}
|
||||
|
||||
List<CompletableFuture<CachedReactions>> futures = new ArrayList<>();
|
||||
message.getReactions().forEach(messageReaction -> futures.add(getCachedReactionFromReaction(messageReaction)));
|
||||
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
|
||||
{
|
||||
CachedAuthor cachedAuthor = CachedAuthor.builder().authorId(message.getAuthor().getIdLong()).isBot(message.getAuthor().isBot()).build();
|
||||
CachedMessage.CachedMessageBuilder builder = CachedMessage.builder()
|
||||
.author(cachedAuthor)
|
||||
.messageId(message.getIdLong())
|
||||
.channelId(message.getChannel().getIdLong())
|
||||
.content(message.getContentRaw())
|
||||
.embeds(embeds)
|
||||
.emotes(emotes)
|
||||
.reactions(convertReactionFuturesToCachedReactions(futures))
|
||||
.timeCreated(Instant.from(message.getTimeCreated()))
|
||||
.attachments(attachments);
|
||||
if(message.isFromGuild()) {
|
||||
builder.serverId(message.getGuild().getIdLong());
|
||||
}
|
||||
future.complete(builder
|
||||
.build());
|
||||
}
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Failed to load reactions for message {}. ", message.getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
private List<CachedReactions> convertReactionFuturesToCachedReactions(List<CompletableFuture<CachedReactions>> futures) {
|
||||
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -294,4 +294,15 @@ public class ChannelServiceBean implements ChannelService {
|
||||
.server(server)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendSimpleTemplateToChannel(Long serverId, Long channelId, String template) {
|
||||
TextChannel textChannel = getTextChannel(serverId, channelId);
|
||||
return sendTextTemplateInChannel(template, new Object(), textChannel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextChannel getTextChannel(Long serverId, Long channelId) {
|
||||
return botService.getTextChannelFromServer(serverId, channelId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.EmoteNotDefinedException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultEmoteManagementService;
|
||||
@@ -16,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -112,8 +114,8 @@ public class EmoteServiceBean implements EmoteService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CachedReaction> getReactionFromMessageByEmote(CachedMessage message, AEmote emote) {
|
||||
return message.getReactions().stream().filter(reaction -> compareAEmote(reaction.getEmote(), emote)).findFirst();
|
||||
public Optional<CachedReactions> getReactionFromMessageByEmote(CachedMessage message, AEmote emote) {
|
||||
return message.getReactions().stream().filter(reaction -> compareCachedEmoteWithAEmote(reaction.getEmote(), emote)).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,6 +131,19 @@ public class EmoteServiceBean implements EmoteService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compareCachedEmoteWithAEmote(CachedEmote a, AEmote b) {
|
||||
if(Boolean.TRUE.equals(a.getCustom()) && Boolean.TRUE.equals(b.getCustom())) {
|
||||
return a.getEmoteId().equals(b.getEmoteId());
|
||||
} else {
|
||||
if(Boolean.FALSE.equals(a.getCustom()) && Boolean.FALSE.equals(b.getCustom())) {
|
||||
return a.getEmoteName().equals(b.getEmoteKey());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AEmote getFakeEmote(Object object) {
|
||||
if(object instanceof Emote) {
|
||||
@@ -163,4 +178,14 @@ public class EmoteServiceBean implements EmoteService {
|
||||
return guild.getEmoteById(emote.getId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Emote> getEmoteFromCachedEmote(CachedEmote cachedEmote) {
|
||||
if(!cachedEmote.getCustom()) {
|
||||
throw new IllegalArgumentException("Given Emote was not a custom emote.");
|
||||
}
|
||||
return botService.retrieveGuildById(cachedEmote.getServerId()).thenCompose(guild ->
|
||||
guild.retrieveEmoteById(cachedEmote.getEmoteId()).submit().thenApply(listedEmote -> listedEmote)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
import dev.sheldan.abstracto.core.exception.FeatureModeNotFoundException;
|
||||
import dev.sheldan.abstracto.core.listener.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.models.template.commands.FeatureModeDisplay;
|
||||
import dev.sheldan.abstracto.core.service.management.DefaultFeatureModeManagement;
|
||||
|
||||
@@ -3,27 +3,17 @@ package dev.sheldan.abstracto.core.service;
|
||||
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
|
||||
import dev.sheldan.abstracto.core.exception.GuildNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.cache.*;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.requests.restaction.pagination.ReactionPaginationAction;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -37,7 +27,7 @@ public class MessageCacheBean implements MessageCache {
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
private CacheEntityService cacheEntityService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
@@ -48,7 +38,7 @@ public class MessageCacheBean implements MessageCache {
|
||||
@CachePut(key = "#message.id")
|
||||
public CompletableFuture<CachedMessage> putMessageInCache(Message message) {
|
||||
log.trace("Adding message {} to cache", message.getId());
|
||||
return concreteSelf.buildCachedMessageFromMessage(message);
|
||||
return cacheEntityService.buildCachedMessageFromMessage(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +73,7 @@ public class MessageCacheBean implements MessageCache {
|
||||
TextChannel textChannel = textChannelByIdOptional.get();
|
||||
textChannel.retrieveMessageById(messageId).queue(message ->
|
||||
|
||||
buildCachedMessageFromMessage(message)
|
||||
cacheEntityService.buildCachedMessageFromMessage(message)
|
||||
.thenAccept(future::complete)
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to load message for caching.", throwable);
|
||||
@@ -104,128 +94,5 @@ public class MessageCacheBean implements MessageCache {
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CachedMessage> buildCachedMessageFromMessage(Message message) {
|
||||
CompletableFuture<CachedMessage> future = new CompletableFuture<>();
|
||||
List<String> attachmentUrls = new ArrayList<>();
|
||||
message.getAttachments().forEach(attachment ->
|
||||
attachmentUrls.add(attachment.getProxyUrl())
|
||||
);
|
||||
List<CachedEmbed> embeds = new ArrayList<>();
|
||||
message.getEmbeds().forEach(embed ->
|
||||
embeds.add(getCachedEmbedFromEmbed(embed))
|
||||
);
|
||||
|
||||
List<CompletableFuture<CachedReaction>> futures = new ArrayList<>();
|
||||
message.getReactions().forEach(messageReaction -> futures.add(concreteSelf.getCachedReactionFromReaction(messageReaction)));
|
||||
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(aVoid ->
|
||||
future.complete(CachedMessage.builder()
|
||||
.authorId(message.getAuthor().getIdLong())
|
||||
.serverId(message.getGuild().getIdLong())
|
||||
.messageId(message.getIdLong())
|
||||
.channelId(message.getChannel().getIdLong())
|
||||
.content(message.getContentRaw())
|
||||
.embeds(embeds)
|
||||
.reactions(getFutures(futures))
|
||||
.timeCreated(Instant.from(message.getTimeCreated()))
|
||||
.attachmentUrls(attachmentUrls)
|
||||
.build())
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Failed to load reactions for message {}. ", message.getId(), throwable);
|
||||
return null;
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
private List<CachedReaction> getFutures(List<CompletableFuture<CachedReaction>> futures) {
|
||||
List<CachedReaction> reactions = new ArrayList<>();
|
||||
futures.forEach(future -> {
|
||||
try {
|
||||
CachedReaction cachedReaction = future.get();
|
||||
reactions.add(cachedReaction);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
log.error("Error while executing future to retrieve reaction.", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
});
|
||||
return reactions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CachedReaction> getCachedReactionFromReaction(MessageReaction reaction) {
|
||||
CompletableFuture<CachedReaction> future = new CompletableFuture<>();
|
||||
ReactionPaginationAction users = reaction.retrieveUsers().cache(false);
|
||||
CachedReaction.CachedReactionBuilder builder = CachedReaction.builder();
|
||||
|
||||
List<Long> aUsers = new ArrayList<>();
|
||||
users.forEachAsync(user -> {
|
||||
concreteSelf.loadUser(reaction, aUsers, user);
|
||||
return false;
|
||||
}).thenAccept(o -> future.complete(builder.build()))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to load reaction users.", throwable);
|
||||
return null;
|
||||
});
|
||||
builder.userInServersIds(aUsers);
|
||||
builder.emote(emoteService.buildAEmoteFromReaction(reaction.getReactionEmote()));
|
||||
return future;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUser(MessageReaction reaction, List<Long> aUsers, User user) {
|
||||
if(reaction.getGuild() != null) {
|
||||
aUsers.add(userInServerManagementService.loadUser(reaction.getGuild().getIdLong(), user.getIdLong()).getUserInServerId());
|
||||
}
|
||||
}
|
||||
|
||||
private CachedEmbed getCachedEmbedFromEmbed(MessageEmbed embed) {
|
||||
CachedEmbed.CachedEmbedBuilder builder = CachedEmbed
|
||||
.builder();
|
||||
MessageEmbed.AuthorInfo author = embed.getAuthor();
|
||||
if(author != null) {
|
||||
builder.author(CachedEmbedAuthor.builder().avatar(author.getProxyIconUrl()).url(author.getUrl()).name(author.getName()).build());
|
||||
}
|
||||
List<MessageEmbed.Field> fields = embed.getFields();
|
||||
if(!fields.isEmpty()) {
|
||||
List<CachedEmbedField> cachedEmbedFields = new ArrayList<>();
|
||||
fields.forEach(field -> {
|
||||
CachedEmbedField build = CachedEmbedField
|
||||
.builder()
|
||||
.name(field.getName())
|
||||
.value(field.getValue())
|
||||
.inline(field.isInline())
|
||||
.build();
|
||||
cachedEmbedFields.add(build);
|
||||
});
|
||||
builder.fields(cachedEmbedFields);
|
||||
}
|
||||
MessageEmbed.ImageInfo image = embed.getImage();
|
||||
if(image != null) {
|
||||
builder.imageUrl(image.getProxyUrl());
|
||||
}
|
||||
Color color = embed.getColor();
|
||||
if(color != null) {
|
||||
CachedEmbedColor build = CachedEmbedColor
|
||||
.builder()
|
||||
.r(color.getRed())
|
||||
.g(color.getGreen())
|
||||
.b(color.getBlue())
|
||||
.build();
|
||||
builder.color(build);
|
||||
}
|
||||
builder.description(embed.getDescription());
|
||||
MessageEmbed.Footer footer = embed.getFooter();
|
||||
if(footer != null) {
|
||||
CachedEmbedFooter build = CachedEmbedFooter
|
||||
.builder()
|
||||
.icon(footer.getProxyIconUrl())
|
||||
.text(footer.getText())
|
||||
.build();
|
||||
builder.footer(build);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.ConfiguredEmoteNotUsableException;
|
||||
import dev.sheldan.abstracto.core.exception.EmoteNotInServerException;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
|
||||
@@ -11,6 +12,7 @@ import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -56,6 +58,13 @@ public class MessageServiceBean implements MessageService {
|
||||
return message.addReaction(unicode).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addDefaultReactionToMessageAsync(String unicode, Long serverId, Long channelId, Long messageId) {
|
||||
TextChannel channel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
return channel.retrieveMessageById(messageId).submit()
|
||||
.thenCompose(message -> self.addDefaultReactionToMessageAsync(unicode, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addReactionToMessageWithFuture(String emoteKey, Long serverId, Message message) {
|
||||
Guild guild = botService.getGuildById(serverId);
|
||||
@@ -103,6 +112,13 @@ public class MessageServiceBean implements MessageService {
|
||||
return message.addReaction(emoteById).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addReactionToMessageWithFuture(String emoteKey, Long serverId, Long channelId, Long messageId) {
|
||||
TextChannel channel = botService.getTextChannelFromServer(serverId, channelId);
|
||||
return channel.retrieveMessageById(messageId).submit()
|
||||
.thenCompose(message -> self.addReactionToMessageWithFuture(emoteKey, serverId, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionFromMessageWithFuture(AEmote emote, Message message) {
|
||||
if(Boolean.TRUE.equals(emote.getCustom())) {
|
||||
@@ -266,6 +282,14 @@ public class MessageServiceBean implements MessageService {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendSimpleTemplateToUser(Long userId, String templateKey) {
|
||||
String text = templateService.renderSimpleTemplate(templateKey);
|
||||
return botService.getUserViaId(userId)
|
||||
.thenCompose(this::openPrivateChannelForUser)
|
||||
.thenCompose(o -> channelService.sendTextToChannel(text, o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendTemplateToUser(User user, String template, Object model) {
|
||||
String message = templateService.renderTemplate(template, model);
|
||||
@@ -274,20 +298,25 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> sendEmbedToUser(User user, String template, Object model) {
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel ->
|
||||
return openPrivateChannelForUser(user).thenCompose(privateChannel ->
|
||||
FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInChannel(template, model, privateChannel)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletableFuture<PrivateChannel> openPrivateChannelForUser(User user) {
|
||||
return user.openPrivateChannel().submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendEmbedToUserWithMessage(User user, String template, Object model) {
|
||||
log.trace("Sending direct message with template {} to user {}.", template, user.getIdLong());
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel ->
|
||||
return openPrivateChannelForUser(user).thenCompose(privateChannel ->
|
||||
channelService.sendEmbedTemplateInChannel(template, model, privateChannel).get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendMessageToSendToUser(User user, MessageToSend messageToSend) {
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel -> channelService.sendMessageToSendToChannel(messageToSend, privateChannel).get(0));
|
||||
return openPrivateChannelForUser(user).thenCompose(privateChannel -> channelService.sendMessageToSendToChannel(messageToSend, privateChannel).get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,6 +333,16 @@ public class MessageServiceBean implements MessageService {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> editMessageInDMChannel(User user, MessageToSend messageToSend, Long messageId) {
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel -> channelService.editMessageInAChannelFuture(messageToSend, privateChannel, messageId).thenApply(message -> null));
|
||||
return openPrivateChannelForUser(user).thenCompose(privateChannel -> channelService.editMessageInAChannelFuture(messageToSend, privateChannel, messageId).thenApply(message -> null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> loadMessageFromCachedMessage(CachedMessage cachedMessage) {
|
||||
return loadMessage(cachedMessage.getServerId(), cachedMessage.getChannelId(), cachedMessage.getMessageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> loadMessage(Long serverId, Long channelId, Long messageId) {
|
||||
return channelService.getTextChannel(serverId, channelId).retrieveMessageById(messageId).submit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class ReactionServiceBean implements ReactionService {
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionFromMessage(CachedReaction reaction, CachedMessage cachedMessage) {
|
||||
return messageService.loadMessageFromCachedMessage(cachedMessage).thenCompose(message -> removeReactionFromMessage(reaction, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionFromMessage(CachedReaction reaction, Message message) {
|
||||
return botService.retrieveUserById(reaction.getUser().getUserId()).thenCompose(user -> {
|
||||
if(reaction.getEmote().getCustom()) {
|
||||
return emoteService.getEmoteFromCachedEmote(reaction.getEmote()).thenCompose(emote ->
|
||||
message.removeReaction(emote, user).submit()
|
||||
);
|
||||
} else {
|
||||
return message.removeReaction(reaction.getEmote().getEmoteName(), user).submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ServerConfigListener;
|
||||
import dev.sheldan.abstracto.core.utils.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
|
||||
|
||||
@@ -4,8 +4,8 @@ import dev.sheldan.abstracto.core.command.exception.ChannelAlreadyInChannelGroup
|
||||
import dev.sheldan.abstracto.core.command.exception.ChannelGroupExistsException;
|
||||
import dev.sheldan.abstracto.core.command.exception.ChannelGroupNotFoundException;
|
||||
import dev.sheldan.abstracto.core.command.exception.ChannelNotInChannelGroupException;
|
||||
import dev.sheldan.abstracto.core.listener.entity.ChannelGroupCreatedListenerManager;
|
||||
import dev.sheldan.abstracto.core.listener.entity.ChannelGroupDeletedListenerManager;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupCreatedListenerManager;
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListenerManager;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.UserInServerNotFoundException;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -29,9 +30,17 @@ public class UserInServerManagementServiceBean implements UserInServerManagement
|
||||
|
||||
@Override
|
||||
public AUserInAServer loadUser(Long serverId, Long userId) {
|
||||
AUser user = userManagementService.loadUser(userId);
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
return loadUser(server, user);
|
||||
return userInServerRepository.findByServerReference_IdAndUserReference_Id(serverId, userId).orElseThrow(() -> new UserInServerNotFoundException(0L));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserInAServer loadUser(ServerUser serverUser) {
|
||||
return loadUser(serverUser.getServerId(), serverUser.getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AUserInAServer> loadUserOptional(Long serverId, Long userId) {
|
||||
return userInServerRepository.findByServerReference_IdAndUserReference_Id(serverId, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,13 +58,13 @@ public class UserInServerManagementServiceBean implements UserInServerManagement
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AUserInAServer> loadUserConditional(Long userInServerId) {
|
||||
public Optional<AUserInAServer> loadUserOptional(Long userInServerId) {
|
||||
return userInServerRepository.findById(userInServerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AUserInAServer loadUser(Long userInServerId) {
|
||||
return loadUserConditional(userInServerId).orElseThrow(() -> new UserInServerNotFoundException(userInServerId));
|
||||
return loadUserOptional(userInServerId).orElseThrow(() -> new UserInServerNotFoundException(userInServerId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.core.utils;
|
||||
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class BeanUtils {
|
||||
|
||||
public static <T extends Prioritized> void sortPrioritizedListeners(List<T> prioritized) {
|
||||
if(prioritized != null) {
|
||||
prioritized.sort(Comparator.comparing(Prioritized::getPriority).reversed());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
abstracto.listener.default.maxPoolSize=5
|
||||
abstracto.listener.default.corePoolSize=1
|
||||
abstracto.listener.default.keepAliveSeconds=60
|
||||
|
||||
|
||||
abstracto.listener.joinListener.maxPoolSize=5
|
||||
abstracto.listener.joinListener.corePoolSize=1
|
||||
abstracto.listener.joinListener.keepAliveSeconds=60
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.sync.entity.FeatureFlagListener;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeature;
|
||||
import dev.sheldan.abstracto.core.models.database.AFeatureFlag;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.config.FeatureMode;
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core;
|
||||
|
||||
public interface Prioritized {
|
||||
Integer getPriority();
|
||||
@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.core.command;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.listener.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionResult;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameters;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.UnParsedCommandParameter;
|
||||
import dev.sheldan.abstracto.core.command.models.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
@@ -25,5 +26,6 @@ public interface CommandService {
|
||||
void disAllowCommandForRole(ACommand aCommand, ARole role);
|
||||
void disAllowFeatureForRole(FeatureEnum featureEnum, ARole role);
|
||||
ConditionResult isCommandExecutable(Command command, CommandContext commandContext);
|
||||
UnParsedCommandParameter getUnParsedCommandParameter(String messageContent);
|
||||
CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.execution;
|
||||
|
||||
public interface ResultAware {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.execution.result;
|
||||
|
||||
public interface ExecutionResult {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.sheldan.abstracto.core.execution.result;
|
||||
|
||||
public enum MessageReceivedListenerResult implements ExecutionResult {
|
||||
IGNORED, PROCESSED, DELETED
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.execution.result.ExecutionResult;
|
||||
import net.dv8tion.jda.api.events.Event;
|
||||
|
||||
public interface Consumable {
|
||||
default boolean shouldConsume(Event event, ExecutionResult result) { return false; }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
public interface MessageReceivedListener extends FeatureAware, Prioritized {
|
||||
void execute(Message message);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
|
||||
public interface ReactedAddedListener extends FeatureAware, Prioritized {
|
||||
void executeReactionAdded(CachedMessage message, GuildMessageReactionAddEvent event, AUserInAServer userAdding);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
|
||||
|
||||
public interface ReactedRemovedListener extends FeatureAware, Prioritized {
|
||||
void executeReactionRemoved(CachedMessage message, GuildMessageReactionRemoveEvent reaction, AUserInAServer userRemoving);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
|
||||
public interface AsyncEmoteCreatedListener extends FeatureAware, Prioritized {
|
||||
void emoteCreated(CachedEmote createdEmote);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
|
||||
public interface AsyncEmoteDeletedListener extends FeatureAware, Prioritized {
|
||||
void emoteDeleted(CachedEmote deletedEmote);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
|
||||
public interface AsyncEmoteUpdatedListener extends FeatureAware, Prioritized {
|
||||
void emoteUpdated(CachedEmote updatedEmote, String oldValue, String newValue);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
|
||||
public interface AsyncJoinListener extends FeatureAware {
|
||||
void execute(ServerUser joiningUser);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
|
||||
public interface AsyncLeaveListener extends FeatureAware {
|
||||
void execute(ServerUser serverUser);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface AsyncMessageDeletedListener extends FeatureAware {
|
||||
void execute(CachedMessage messageBefore);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
||||
|
||||
public interface AsyncMessageEmbeddedListener extends FeatureAware {
|
||||
void execute(GuildMessageEmbedEventModel eventModel);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface AsyncMessageReceivedListener extends FeatureAware {
|
||||
void execute(CachedMessage message);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface AsyncMessageTextUpdatedListener extends FeatureAware {
|
||||
void execute(CachedMessage messageBefore, CachedMessage messageAfter);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface AsyncPrivateMessageReceivedListener extends FeatureAware {
|
||||
void execute(CachedMessage message);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
|
||||
public interface AsyncReactionAddedListener extends FeatureAware {
|
||||
void executeReactionAdded(CachedMessage message, CachedReactions addedReaction, ServerUser userAdding);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface AsyncReactionClearedListener extends FeatureAware {
|
||||
void executeReactionCleared(CachedMessage message);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
|
||||
|
||||
public interface AsyncReactionRemovedListener extends FeatureAware {
|
||||
void executeReactionRemoved(CachedMessage message, CachedReactions removedReaction, ServerUser userRemoving);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener.entity;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener.entity;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AChannelGroup;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.entity;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
|
||||
public interface EmoteCreatedListener extends FeatureAware, Prioritized {
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
|
||||
public interface EmoteDeletedListener extends FeatureAware, Prioritized {
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import net.dv8tion.jda.api.entities.Emote;
|
||||
|
||||
public interface EmoteUpdatedListener extends FeatureAware, Prioritized {
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
|
||||
import dev.sheldan.abstracto.core.models.GuildChannelMember;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
||||
|
||||
public interface MessageEmbeddedListener extends FeatureAware, Prioritized {
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.listener.Consumable;
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
public interface MessageReceivedListener extends FeatureAware, Prioritized, Consumable {
|
||||
MessageReceivedListenerResult execute(Message message);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
public interface PrivateMessageReceivedListener extends FeatureAware, Prioritized {
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
|
||||
public interface ReactionAddedListener extends FeatureAware, Prioritized {
|
||||
void executeReactionAdded(CachedMessage message, GuildMessageReactionAddEvent event, ServerUser serverUser);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.listener;
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
|
||||
public interface ReactionClearedListener extends FeatureAware, Prioritized {
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
||||
|
||||
import dev.sheldan.abstracto.core.FeatureAware;
|
||||
import dev.sheldan.abstracto.core.Prioritized;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
|
||||
|
||||
public interface ReactionRemovedListener extends FeatureAware, Prioritized {
|
||||
void executeReactionRemoved(CachedMessage message, GuildMessageReactionRemoveEvent reaction, ServerUser serverUser);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.core.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@EqualsAndHashCode
|
||||
public class ServerUser {
|
||||
private Long serverId;
|
||||
private Long userId;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.sheldan.abstracto.core.models.cache;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CachedAttachment {
|
||||
private String url;
|
||||
private String proxyUrl;
|
||||
private String fileName;
|
||||
private Integer size;
|
||||
private Integer height;
|
||||
private Integer width;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.abstracto.core.models.cache;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CachedAuthor {
|
||||
private Long authorId;
|
||||
private Boolean isBot;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.core.models.cache;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.EmbedType;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
@@ -15,9 +16,10 @@ public class CachedEmbed {
|
||||
private CachedEmbedTitle title;
|
||||
private CachedEmbedColor color;
|
||||
private String description;
|
||||
private String thumbnail;
|
||||
private String imageUrl;
|
||||
private CachedThumbnail cachedThumbnail;
|
||||
private CachedImageInfo cachedImageInfo;
|
||||
private List<CachedEmbedField> fields;
|
||||
private CachedEmbedFooter footer;
|
||||
private OffsetDateTime timeStamp;
|
||||
private EmbedType type;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user