mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-12-26 17:18:29 +01:00
Fix for non-text channels in ChannelConfigHelper, resolution by full channel atom. Fix forwarding messages from non-text, non-thread channels to Minecraft. Add test for voice channel messages
This commit is contained in:
parent
611f8bba36
commit
ed82f642f1
@ -24,6 +24,7 @@
|
||||
package com.discordsrv.api.events.message.process.discord;
|
||||
|
||||
import com.discordsrv.api.channel.GameChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.events.Cancellable;
|
||||
import com.discordsrv.api.events.Processable;
|
||||
@ -51,6 +52,10 @@ public class DiscordChatMessageProcessEvent implements Cancellable, Processable.
|
||||
this.destinationChannel = destinationChannel;
|
||||
}
|
||||
|
||||
public DiscordMessageChannel getChannel() {
|
||||
return message.getChannel();
|
||||
}
|
||||
|
||||
public ReceivedDiscordMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
@ -23,9 +23,7 @@
|
||||
|
||||
package com.discordsrv.api.events.message.receive.discord;
|
||||
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordTextChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordThreadChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.*;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.events.Cancellable;
|
||||
@ -39,15 +37,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class DiscordChatMessageReceiveEvent implements Cancellable {
|
||||
|
||||
private final ReceivedDiscordMessage message;
|
||||
private final DiscordMessageChannel channel;
|
||||
private final DiscordGuildMessageChannel channel;
|
||||
private boolean cancelled;
|
||||
|
||||
public DiscordChatMessageReceiveEvent(@NotNull ReceivedDiscordMessage discordMessage, @NotNull DiscordMessageChannel channel) {
|
||||
public DiscordChatMessageReceiveEvent(@NotNull ReceivedDiscordMessage discordMessage, @NotNull DiscordGuildMessageChannel channel) {
|
||||
this.message = discordMessage;
|
||||
this.channel = channel;
|
||||
if (!(channel instanceof DiscordTextChannel) && !(channel instanceof DiscordThreadChannel)) {
|
||||
throw new IllegalStateException("Cannot process messages that aren't from a text channel or thread");
|
||||
}
|
||||
}
|
||||
|
||||
public ReceivedDiscordMessage getMessage() {
|
||||
@ -59,13 +54,7 @@ public class DiscordChatMessageReceiveEvent implements Cancellable {
|
||||
}
|
||||
|
||||
public DiscordGuild getGuild() {
|
||||
if (channel instanceof DiscordTextChannel) {
|
||||
return ((DiscordTextChannel) channel).getGuild();
|
||||
} else if (channel instanceof DiscordThreadChannel) {
|
||||
return ((DiscordThreadChannel) channel).getParentChannel().getGuild();
|
||||
} else {
|
||||
throw new IllegalStateException("Message isn't from a text channel or thread");
|
||||
}
|
||||
return channel.getGuild();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,7 +112,7 @@ public abstract class BroadcastCommand implements GameCommandExecutor, GameComma
|
||||
channels.add(messageChannel);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
BaseChannelConfig channelConfig = discordSRV.channelConfig().resolve(null, channel);
|
||||
BaseChannelConfig channelConfig = discordSRV.channelConfig().resolve(channel);
|
||||
CC config = channelConfig != null ? (CC) channelConfig : null;
|
||||
|
||||
if (config != null) {
|
||||
|
@ -22,6 +22,8 @@ import com.discordsrv.api.channel.GameChannel;
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.api.discord.connection.details.DiscordGatewayIntent;
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordGuildMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||
@ -95,12 +97,19 @@ public class DiscordChatMessageModule extends AbstractModule<DiscordSRV> {
|
||||
|
||||
@Subscribe
|
||||
public void onDiscordMessageReceived(DiscordMessageReceiveEvent event) {
|
||||
if (!discordSRV.isReady() || event.getMessage().isFromSelf()
|
||||
|| !(event.getTextChannel() != null || event.getThreadChannel() != null)) {
|
||||
if (!discordSRV.isReady() || event.getMessage().isFromSelf()) {
|
||||
return;
|
||||
}
|
||||
|
||||
discordSRV.eventBus().publish(new DiscordChatMessageReceiveEvent(event.getMessage(), event.getChannel()));
|
||||
DiscordChannel channel = event.getChannel();
|
||||
if (!(channel instanceof DiscordGuildMessageChannel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
discordSRV.eventBus().publish(new DiscordChatMessageReceiveEvent(
|
||||
event.getMessage(),
|
||||
(DiscordGuildMessageChannel) channel
|
||||
));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -20,7 +20,6 @@ package com.discordsrv.common.helper;
|
||||
|
||||
import com.discordsrv.api.channel.GameChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordTextChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordThreadChannel;
|
||||
import com.discordsrv.api.events.channel.GameChannelLookupEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
@ -30,6 +29,8 @@ import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||
import com.discordsrv.common.config.main.generic.DestinationConfig;
|
||||
import com.discordsrv.common.config.main.generic.ThreadConfig;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@ -45,6 +46,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class ChannelConfigHelper {
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final Logger logger;
|
||||
|
||||
// game channel name eg. "global" -> game channel ("discordsrv:global")
|
||||
private final LoadingCache<String, GameChannel> nameToChannelCache;
|
||||
@ -53,11 +55,13 @@ public class ChannelConfigHelper {
|
||||
private final Map<String, BaseChannelConfig> configs;
|
||||
|
||||
// caches for Discord channel -> config
|
||||
private final Map<Long, Map<String, BaseChannelConfig>> textChannelToConfigMap;
|
||||
private final Map<Long, Map<String, BaseChannelConfig>> messageChannelToConfigMap;
|
||||
private final Map<Pair<Long, String>, Map<String, BaseChannelConfig>> threadToConfigMap;
|
||||
|
||||
public ChannelConfigHelper(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "CHANNEL_CONFIG_HELPER");
|
||||
|
||||
this.nameToChannelCache = discordSRV.caffeineBuilder()
|
||||
.expireAfterWrite(60, TimeUnit.SECONDS)
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
@ -65,21 +69,33 @@ public class ChannelConfigHelper {
|
||||
.build(new CacheLoader<String, GameChannel>() {
|
||||
|
||||
@Override
|
||||
public @Nullable GameChannel load(@NotNull String channelName) {
|
||||
GameChannelLookupEvent event = new GameChannelLookupEvent(null, channelName);
|
||||
public @Nullable GameChannel load(@NotNull String channelAtom) {
|
||||
Pair<String, String> channelPair = parseOwnerAndChannel(channelAtom);
|
||||
|
||||
GameChannelLookupEvent event = new GameChannelLookupEvent(channelPair.getKey(), channelPair.getValue());
|
||||
discordSRV.eventBus().publish(event);
|
||||
if (!event.isProcessed()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return event.getChannelFromProcessing();
|
||||
GameChannel channel = event.getChannelFromProcessing();
|
||||
logger.trace(channelAtom + " looked up to " + GameChannel.toString(channel));
|
||||
return channel;
|
||||
}
|
||||
});
|
||||
this.configs = new HashMap<>();
|
||||
this.textChannelToConfigMap = new HashMap<>();
|
||||
this.messageChannelToConfigMap = new HashMap<>();
|
||||
this.threadToConfigMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
private Pair<String, String> parseOwnerAndChannel(String channelAtom) {
|
||||
String[] split = channelAtom.split(":", 2);
|
||||
String channelName = split[split.length - 1];
|
||||
String ownerName = split.length == 2 ? split[0] : null;
|
||||
|
||||
return Pair.of(ownerName, channelName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private BaseChannelConfig map(BaseChannelConfig defaultConfig, BaseChannelConfig config)
|
||||
throws SerializationException {
|
||||
@ -120,7 +136,7 @@ public class ChannelConfigHelper {
|
||||
this.configs.putAll(configs);
|
||||
}
|
||||
|
||||
Map<Long, Map<String, BaseChannelConfig>> text = new HashMap<>();
|
||||
Map<Long, Map<String, BaseChannelConfig>> messageChannel = new HashMap<>();
|
||||
Map<Pair<Long, String>, Map<String, BaseChannelConfig>> thread = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, BaseChannelConfig> entry : channels().entrySet()) {
|
||||
@ -132,7 +148,7 @@ public class ChannelConfigHelper {
|
||||
List<Long> channelIds = destination.channelIds;
|
||||
if (channelIds != null) {
|
||||
for (long channelId : channelIds) {
|
||||
text.computeIfAbsent(channelId, key -> new LinkedHashMap<>())
|
||||
messageChannel.computeIfAbsent(channelId, key -> new LinkedHashMap<>())
|
||||
.put(channelName, value);
|
||||
}
|
||||
}
|
||||
@ -151,9 +167,9 @@ public class ChannelConfigHelper {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (textChannelToConfigMap) {
|
||||
textChannelToConfigMap.clear();
|
||||
textChannelToConfigMap.putAll(text);
|
||||
synchronized (messageChannelToConfigMap) {
|
||||
messageChannelToConfigMap.clear();
|
||||
messageChannelToConfigMap.putAll(messageChannel);
|
||||
}
|
||||
synchronized (threadToConfigMap) {
|
||||
threadToConfigMap.clear();
|
||||
@ -204,6 +220,12 @@ public class ChannelConfigHelper {
|
||||
return resolve(gameChannel.getOwnerName(), gameChannel.getChannelName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BaseChannelConfig resolve(@NotNull String channelAtom) {
|
||||
Pair<String, String> channelPair = parseOwnerAndChannel(channelAtom);
|
||||
return resolve(channelPair.getKey(), channelPair.getValue());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BaseChannelConfig resolve(@Nullable String ownerName, @NotNull String channelName) {
|
||||
if (ownerName != null) {
|
||||
@ -216,6 +238,7 @@ public class ChannelConfigHelper {
|
||||
}
|
||||
|
||||
// Check if this owner has the highest priority for this channel name
|
||||
// in case they are, we can also use "channel" config directly
|
||||
GameChannel gameChannel = nameToChannelCache.get(channelName);
|
||||
if (gameChannel != null && gameChannel.getOwnerName().equalsIgnoreCase(ownerName)) {
|
||||
config = findChannel(channelName);
|
||||
@ -249,19 +272,16 @@ public class ChannelConfigHelper {
|
||||
}
|
||||
|
||||
private Map<String, BaseChannelConfig> get(DiscordMessageChannel channel) {
|
||||
Map<String, BaseChannelConfig> pairs = null;
|
||||
if (channel instanceof DiscordTextChannel) {
|
||||
pairs = getByTextChannel((DiscordTextChannel) channel);
|
||||
} else if (channel instanceof DiscordThreadChannel) {
|
||||
pairs = getByThreadChannel((DiscordThreadChannel) channel);
|
||||
if (channel instanceof DiscordThreadChannel) {
|
||||
return getByThreadChannel((DiscordThreadChannel) channel);
|
||||
}
|
||||
|
||||
return pairs;
|
||||
return getByMessageChannel(channel);
|
||||
}
|
||||
|
||||
private Map<String, BaseChannelConfig> getByTextChannel(DiscordTextChannel channel) {
|
||||
synchronized (textChannelToConfigMap) {
|
||||
return textChannelToConfigMap.get(channel.getId());
|
||||
private Map<String, BaseChannelConfig> getByMessageChannel(DiscordMessageChannel channel) {
|
||||
synchronized (messageChannelToConfigMap) {
|
||||
return messageChannelToConfigMap.get(channel.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,16 +26,18 @@ import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
public class FullBootExtension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
|
||||
|
||||
public static String BOT_TOKEN = System.getenv("DISCORDSRV_AUTOTEST_BOT_TOKEN");
|
||||
public static String TEST_CHANNEL_ID = System.getenv("DISCORDSRV_AUTOTEST_CHANNEL_ID");
|
||||
public static String TEXT_CHANNEL_ID = System.getenv("DISCORDSRV_AUTOTEST_CHANNEL_ID");
|
||||
public static String FORUM_CHANNEL_ID = System.getenv("DISCORDSRV_AUTOTEST_FORUM_ID");
|
||||
public static String VOICE_CHANNEL_ID = System.getenv("DISCORDSRV_AUTOTEST_VOICE_ID");
|
||||
|
||||
public boolean started = false;
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
Assumptions.assumeTrue(BOT_TOKEN != null, "Automated testing bot token");
|
||||
Assumptions.assumeTrue(TEST_CHANNEL_ID != null, "Automated testing channel id");
|
||||
Assumptions.assumeTrue(FORUM_CHANNEL_ID != null, "Automated testing forum id");
|
||||
Assumptions.assumeTrue(TEXT_CHANNEL_ID != null, "Automated testing text channel id");
|
||||
Assumptions.assumeTrue(FORUM_CHANNEL_ID != null, "Automated testing forum channel id");
|
||||
Assumptions.assumeTrue(VOICE_CHANNEL_ID != null, "Automated testing voice channel id");
|
||||
|
||||
if (started) return;
|
||||
started = true;
|
||||
|
@ -241,22 +241,24 @@ public class MockDiscordSRV extends AbstractDiscordSRV<IBootstrap, MainConfig, C
|
||||
public MainConfig config() {
|
||||
MainConfig config = new MainConfig() {};
|
||||
|
||||
if (StringUtils.isNotEmpty(FullBootExtension.TEST_CHANNEL_ID) && StringUtils.isNotEmpty(FullBootExtension.FORUM_CHANNEL_ID)) {
|
||||
if (StringUtils.isNotEmpty(FullBootExtension.TEXT_CHANNEL_ID) && StringUtils.isNotEmpty(FullBootExtension.FORUM_CHANNEL_ID)) {
|
||||
ChannelConfig global = (ChannelConfig) config.channels.get(GameChannel.DEFAULT_NAME);
|
||||
DestinationConfig destination = global.destination = new DestinationConfig();
|
||||
|
||||
long channelId = Long.parseLong(FullBootExtension.TEST_CHANNEL_ID);
|
||||
long textChannelId = Long.parseLong(FullBootExtension.TEXT_CHANNEL_ID);
|
||||
long voiceChannelId = Long.parseLong(FullBootExtension.VOICE_CHANNEL_ID);
|
||||
long forumId = Long.parseLong(FullBootExtension.FORUM_CHANNEL_ID);
|
||||
|
||||
List<Long> channelIds = destination.channelIds;
|
||||
channelIds.clear();
|
||||
channelIds.add(channelId);
|
||||
channelIds.add(textChannelId);
|
||||
channelIds.add(voiceChannelId);
|
||||
|
||||
List<ThreadConfig> threadConfigs = destination.threads;
|
||||
threadConfigs.clear();
|
||||
|
||||
ThreadConfig thread = new ThreadConfig();
|
||||
thread.channelId = channelId;
|
||||
thread.channelId = textChannelId;
|
||||
threadConfigs.add(thread);
|
||||
|
||||
ThreadConfig forumThread = new ThreadConfig();
|
||||
|
@ -21,6 +21,7 @@ package com.discordsrv.common.messageforwarding.game;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordTextChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordThreadChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordVoiceChannel;
|
||||
import com.discordsrv.api.discord.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.eventbus.EventBus;
|
||||
import com.discordsrv.api.eventbus.Subscribe;
|
||||
@ -163,6 +164,7 @@ public class MinecraftToDiscordChatMessageTest {
|
||||
@Subscribe
|
||||
public void onForwarded(GameChatMessageForwardedEvent event) {
|
||||
int text = 0;
|
||||
int voice = 0;
|
||||
int thread = 0;
|
||||
for (ReceivedDiscordMessage message : event.getDiscordMessage().getMessages()) {
|
||||
String content = message.getContent();
|
||||
@ -170,13 +172,15 @@ public class MinecraftToDiscordChatMessageTest {
|
||||
DiscordMessageChannel channel = message.getChannel();
|
||||
if (channel instanceof DiscordTextChannel) {
|
||||
text++;
|
||||
} else if (channel instanceof DiscordVoiceChannel) {
|
||||
voice++;
|
||||
} else if (channel instanceof DiscordThreadChannel) {
|
||||
thread++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
success.complete(text == 1 && thread == 2);
|
||||
success.complete(text == 1 && voice == 1 && thread == 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user