From ad17d4c5e7757b45d79215e98063ff74bda0816d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Mon, 11 Apr 2022 22:23:07 +0200 Subject: [PATCH] Handle message related events from unexpected channel types (#2078) --- .../handle/InteractionCreateHandler.java | 14 +++++++- .../handle/MessageBulkDeleteHandler.java | 29 +++++++++++---- .../internal/handle/MessageCreateHandler.java | 6 ++++ .../internal/handle/MessageDeleteHandler.java | 32 ++++++++++++----- .../MessageReactionBulkRemoveHandler.java | 29 +++++++++++---- .../MessageReactionClearEmoteHandler.java | 21 ++++++----- .../handle/MessageReactionHandler.java | 19 +++++----- .../internal/handle/MessageUpdateHandler.java | 35 +++++++++++++------ .../internal/handle/TypingStartHandler.java | 8 +---- 9 files changed, 135 insertions(+), 58 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/handle/InteractionCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/InteractionCreateHandler.java index d8a87b160d..960f4807dc 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/InteractionCreateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/InteractionCreateHandler.java @@ -16,6 +16,8 @@ package net.dv8tion.jda.internal.handle; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent; import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent; @@ -55,10 +57,20 @@ protected Long handleInternally(DataObject content) } long guildId = content.getUnsignedLong("guild_id", 0); + Guild guild = api.getGuildById(guildId); if (api.getGuildSetupController().isLocked(guildId)) return guildId; - if (guildId != 0 && api.getGuildById(guildId) == null) + if (guildId != 0 && guild == null) return null; // discard event if it is not from a guild we are currently in + if (guild != null) + { + GuildChannel channel = guild.getGuildChannelById(content.getUnsignedLong("channel_id", 0)); + if (channel == null || !channel.getType().isMessage()) // TODO: This might break when interactions can be used outside of message channels in the future, not the case right now though! + { + WebSocketClient.LOG.debug("Discarding INTERACTION_CREATE event from unexpected channel type. Channel: {}", channel); + return null; + } + } switch (InteractionType.fromKey(type)) { diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageBulkDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageBulkDeleteHandler.java index 557fe11269..9f3628ff5c 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageBulkDeleteHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageBulkDeleteHandler.java @@ -16,11 +16,14 @@ package net.dv8tion.jda.internal.handle; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.GuildMessageChannel; import net.dv8tion.jda.api.events.message.MessageBulkDeleteEvent; import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.requests.WebSocketClient; import java.util.List; import java.util.stream.Collectors; @@ -35,11 +38,20 @@ public MessageBulkDeleteHandler(JDAImpl api) @Override protected Long handleInternally(DataObject content) { + Guild guild = null; if (!content.isNull("guild_id")) { long guildId = content.getLong("guild_id"); if (getJDA().getGuildSetupController().isLocked(guildId)) return guildId; + + guild = api.getGuildById(guildId); + if (guild == null) + { + EventCache.LOG.debug("Caching MESSAGE_DELETE event for guild that is not currently cached. GuildID: {}", guildId); + api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } } final long channelId = content.getLong("channel_id"); @@ -57,15 +69,20 @@ protected Long handleInternally(DataObject content) } else { - //TODO-v5-unified-channel-cache - GuildMessageChannel channel = getJDA().getTextChannelById(channelId); - if (channel == null) - channel = getJDA().getNewsChannelById(channelId); - if (channel == null) - channel = getJDA().getThreadChannelById(channelId); + GuildMessageChannel channel = getJDA().getChannelById(GuildMessageChannel.class, channelId); if (channel == null) { + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_DELETE event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Received a Bulk Message Delete for a GuildMessageChannel that is not yet cached."); return null; diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageCreateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageCreateHandler.java index 1039926098..0ca03d8943 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageCreateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageCreateHandler.java @@ -74,6 +74,12 @@ protected Long handleInternally(DataObject content) case EntityBuilder.MISSING_CHANNEL: { final long channelId = content.getLong("channel_id"); + if (guild != null && guild.getGuildChannelById(channelId) != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_CREATE event for unexpected channel type. Channel: {}", guild.getGuildChannelById(channelId)); + return null; + } + jda.getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Received a message for a channel that JDA does not currently have cached"); return null; diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageDeleteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageDeleteHandler.java index 4b8748a397..f032512591 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageDeleteHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageDeleteHandler.java @@ -15,12 +15,14 @@ */ package net.dv8tion.jda.internal.handle; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.MessageDeleteEvent; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.ThreadChannelImpl; -import net.dv8tion.jda.internal.entities.mixin.channel.middleman.MessageChannelMixin; +import net.dv8tion.jda.internal.requests.WebSocketClient; public class MessageDeleteHandler extends SocketHandler { @@ -33,26 +35,38 @@ public MessageDeleteHandler(JDAImpl api) @Override protected Long handleInternally(DataObject content) { + Guild guild = null; if (!content.isNull("guild_id")) { long guildId = content.getLong("guild_id"); if (getJDA().getGuildSetupController().isLocked(guildId)) return guildId; + + guild = api.getGuildById(guildId); + if (guild == null) + { + EventCache.LOG.debug("Caching MESSAGE_DELETE event for guild that is not currently cached. GuildID: {}", guildId); + api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } } final long messageId = content.getLong("id"); final long channelId = content.getLong("channel_id"); - //TODO-v5-unified-channel-cache - MessageChannel channel = getJDA().getTextChannelById(channelId); - if (channel == null) - channel = getJDA().getNewsChannelById(channelId); - if (channel == null) - channel = getJDA().getThreadChannelById(channelId); - if (channel == null) - channel = getJDA().getPrivateChannelById(channelId); + MessageChannel channel = getJDA().getChannelById(MessageChannel.class, channelId); if (channel == null) { + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_DELETE event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Got message delete for a channel/group that is not yet cached. ChannelId: {}", channelId); return null; diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionBulkRemoveHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionBulkRemoveHandler.java index 693a017a1b..4422bada95 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionBulkRemoveHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionBulkRemoveHandler.java @@ -16,10 +16,13 @@ package net.dv8tion.jda.internal.handle; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.GuildChannel; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.events.message.react.MessageReactionRemoveAllEvent; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.requests.WebSocketClient; public class MessageReactionBulkRemoveHandler extends SocketHandler { @@ -35,21 +38,35 @@ protected Long handleInternally(DataObject content) final long channelId = content.getLong("channel_id"); JDAImpl jda = getJDA(); + Guild guild = null; if (!content.isNull("guild_id")) { long guildId = content.getUnsignedLong("guild_id"); if (api.getGuildSetupController().isLocked(guildId)) return guildId; + + guild = api.getGuildById(guildId); + if (guild == null) + { + EventCache.LOG.debug("Caching MESSAGE_REACTION_REMOVE_ALL event for guild that is not currently cached. GuildID: {}", guildId); + api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + return null; + } } - //TODO-v5-unified-channel-cache - MessageChannel channel = jda.getTextChannelById(channelId); - if (channel == null) - channel = jda.getNewsChannelById(channelId); - if (channel == null) - channel = jda.getThreadChannelById(channelId); + MessageChannel channel = getJDA().getChannelById(MessageChannel.class, channelId); if (channel == null) { + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_REACTION_REMOVE_ALL event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + jda.getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Received a reaction for a channel that JDA does not currently have cached channel_id: {} message_id: {}", channelId, messageId); return null; diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmoteHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmoteHandler.java index 6997bc8372..0126e5275f 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmoteHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmoteHandler.java @@ -16,14 +16,12 @@ package net.dv8tion.jda.internal.handle; -import net.dv8tion.jda.api.entities.Emote; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.GuildMessageChannel; -import net.dv8tion.jda.api.entities.MessageReaction; +import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEmoteEvent; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; import net.dv8tion.jda.internal.entities.EmoteImpl; +import net.dv8tion.jda.internal.requests.WebSocketClient; public class MessageReactionClearEmoteHandler extends SocketHandler { @@ -48,15 +46,16 @@ protected Long handleInternally(DataObject content) long channelId = content.getUnsignedLong("channel_id"); - //TODO-v5-unified-channel-cache - GuildMessageChannel channel = guild.getTextChannelById(channelId); - if (channel == null) - channel = guild.getNewsChannelById(channelId); - if (channel == null) - channel = guild.getThreadChannelById(channelId); - + GuildMessageChannel channel = guild.getChannelById(GuildMessageChannel.class, channelId); if (channel == null) { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_REACTION_REMOVE_EMOJI event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + EventCache.LOG.debug("Caching MESSAGE_REACTION_REMOVE_EMOJI event for unknown channel {}", channelId); getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); return null; diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java index 6de60fa586..7ff0a1b7d1 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java @@ -121,16 +121,19 @@ protected Long handleInternally(DataObject content) } } - //TODO-v5-unified-channel-cache - MessageChannel channel = api.getTextChannelById(channelId); - if (channel == null) - channel = api.getNewsChannelById(channelId); - if (channel == null) - channel = api.getThreadChannelById(channelId); - if (channel == null) - channel = api.getPrivateChannelById(channelId); + MessageChannel channel = api.getChannelById(MessageChannel.class, channelId); if (channel == null) { + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding reaction event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + if (guildId != 0) { api.getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageUpdateHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageUpdateHandler.java index d494faf58c..ecfb446904 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageUpdateHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageUpdateHandler.java @@ -93,6 +93,16 @@ private Long handleMessage(DataObject content, Guild guild) case EntityBuilder.MISSING_CHANNEL: { final long channelId = content.getLong("channel_id"); + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_UPDATE event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Received a message update for a channel that JDA does not currently have cached"); return null; @@ -126,15 +136,20 @@ private Long handleMessageEmbed(DataObject content) final long channelId = content.getLong("channel_id"); LinkedList embeds = new LinkedList<>(); - //TODO-v5-unified-channel-cache - //TODO-v5: handle for threads. - MessageChannel channel = getJDA().getTextChannelsView().get(channelId); - if (channel == null) - channel = getJDA().getNewsChannelById(channelId); - if (channel == null) - channel = getJDA().getPrivateChannelsView().get(channelId); + MessageChannel channel = getJDA().getChannelById(MessageChannel.class, channelId); if (channel == null) { + Guild guild = getJDA().getGuildById(content.getUnsignedLong("guild_id", 0L)); + if (guild != null) + { + GuildChannel guildChannel = guild.getGuildChannelById(channelId); + if (guildChannel != null) + { + WebSocketClient.LOG.debug("Discarding MESSAGE_UPDATE event for unexpected channel type. Channel: {}", guildChannel); + return null; + } + } + getJDA().getEventCache().cache(EventCache.Type.CHANNEL, channelId, responseNumber, allContent, this::handle); EventCache.LOG.debug("Received message update for embeds for a channel/group that JDA does not have cached yet."); return null; @@ -145,9 +160,9 @@ private Long handleMessageEmbed(DataObject content) embeds.add(builder.createMessageEmbed(embedsJson.getObject(i))); getJDA().handleEvent( - new MessageEmbedEvent( - getJDA(), responseNumber, - messageId, channel, embeds)); + new MessageEmbedEvent( + getJDA(), responseNumber, + messageId, channel, embeds)); return null; } } diff --git a/src/main/java/net/dv8tion/jda/internal/handle/TypingStartHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/TypingStartHandler.java index 3c37f81bac..efc5f88ef4 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/TypingStartHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/TypingStartHandler.java @@ -52,13 +52,7 @@ else if (guild == null) } final long channelId = content.getLong("channel_id"); - - //TODO-v5-unified-channel-cache - MessageChannel channel = getJDA().getTextChannelsView().get(channelId); - if (channel == null) - channel = getJDA().getNewsChannelView().get(channelId); - if (channel == null) - channel = getJDA().getPrivateChannelsView().get(channelId); + MessageChannel channel = getJDA().getChannelById(MessageChannel.class, channelId); if (channel == null) return null; //We don't have the channel cached yet. We chose not to cache this event // because that happen very often and could easily fill up the EventCache if