From a1c719bf9ccc20434c59639db247c6ae757a6b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sat, 30 Sep 2023 13:36:15 +0200 Subject: [PATCH 1/2] Implement super reaction handling --- .../jda/api/entities/MessageReaction.java | 83 ++++++++++++++++--- .../jda/internal/entities/EntityBuilder.java | 11 ++- .../MessageReactionClearEmojiHandler.java | 8 +- .../handle/MessageReactionHandler.java | 8 +- 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/MessageReaction.java b/src/main/java/net/dv8tion/jda/api/entities/MessageReaction.java index 820e2389f7..19eee4878a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/MessageReaction.java +++ b/src/main/java/net/dv8tion/jda/api/entities/MessageReaction.java @@ -54,8 +54,8 @@ public class MessageReaction private final MessageChannel channel; private final EmojiUnion emoji; private final long messageId; - private final boolean self; - private final int count; + private final boolean[] self; + private final int[] counts; /** * Creates a new MessageReaction instance @@ -67,17 +67,19 @@ public class MessageReaction * @param messageId * The message id this reaction is attached to * @param self - * Whether we already reacted with this Reaction - * @param count - * The amount of people that reacted with this Reaction + * Whether we already reacted with this Reaction, + * as an array of {@code [normal, super]} + * @param counts + * The amount of people that reacted with this Reaction, + * as an array of {@code [total, normal, super]} */ - public MessageReaction(@Nonnull MessageChannel channel, @Nonnull EmojiUnion emoji, long messageId, boolean self, int count) + public MessageReaction(@Nonnull MessageChannel channel, @Nonnull EmojiUnion emoji, long messageId, boolean[] self, int[] counts) { this.channel = channel; this.emoji = emoji; this.messageId = messageId; this.self = self; - this.count = count; + this.counts = counts; } /** @@ -92,16 +94,35 @@ public JDA getJDA() } /** - * Whether the currently logged in account has reacted with this reaction + * Whether the currently logged in account has reacted with this reaction at all, including both super and normal. * *

This will always be false for events. Discord does not provide this information for reaction events. * You can use {@link MessageChannel#retrieveMessageById(String)} to get this information on a complete message. * * @return True, if we reacted with this reaction + * + * @see #isSelf(ReactionType) */ public boolean isSelf() { - return self; + return self[0] || self[1]; + } + + /** + * Whether the currently logged in account has reacted with this reaction as specifically a super or normal reaction. + * + *

This will always be false for events. Discord does not provide this information for reaction events. + * You can use {@link MessageChannel#retrieveMessageById(String)} to get this information on a complete message. + * + * @param type + * The specific type of reaction + * + * @return True, if we reacted with this reaction + */ + public boolean isSelf(@Nonnull ReactionType type) + { + Checks.notNull(type, "Type"); + return self[type == ReactionType.NORMAL ? 0 : 1]; } /** @@ -115,11 +136,11 @@ public boolean isSelf() */ public boolean hasCount() { - return count >= 0; + return counts != null; } /** - * The amount of users that already reacted with this Reaction + * The total amount of users that already reacted with this Reaction. *
This is not updated, it is a {@code final int} per Reaction instance * *

This value is not available in events such as {@link net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent MessageReactionAddEvent} @@ -130,12 +151,40 @@ public boolean hasCount() * If this MessageReaction is from an event which does not provide a count * * @return The amount of users that reacted with this Reaction + * + * @see #getCount(ReactionType) */ public int getCount() { if (!hasCount()) throw new IllegalStateException("Cannot retrieve count for this MessageReaction!"); - return count; + return counts[0]; + } + + /** + * The specific amount of users that already reacted with this Reaction. + *
This is not updated, it is a {@code final int} per Reaction instance + * + *

This value is not available in events such as {@link net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent MessageReactionAddEvent} + * and {@link net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEvent MessageReactionRemoveEvent} in which case an + * {@link java.lang.IllegalStateException IllegalStateException} is thrown! + * + * @param type + * The specific type of reaction + * + * @throws java.lang.IllegalStateException + * If this MessageReaction is from an event which does not provide a count + * + * @return The amount of users that reacted with this Reaction + * + * @see #getCount() + */ + public int getCount(@Nonnull ReactionType type) + { + if (!hasCount()) + throw new IllegalStateException("Cannot retrieve count for this MessageReaction!"); + Checks.notNull(type, "Type"); + return counts[type == ReactionType.NORMAL ? 1 : 2]; } /** @@ -392,7 +441,7 @@ public boolean equals(Object obj) return false; MessageReaction r = (MessageReaction) obj; return r.emoji.equals(emoji) - && r.self == self + && r.isSelf() == this.isSelf() && r.messageId == messageId; } @@ -404,4 +453,12 @@ public String toString() .addMetadata("emoji", emoji) .toString(); } + + /** + * Type of reaction. + */ + public enum ReactionType + { + NORMAL, SUPER + } } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index a3514369c7..0c56e05e70 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -1889,8 +1889,15 @@ private static MessageActivity createMessageActivity(DataObject jsonObject) public MessageReaction createMessageReaction(MessageChannel chan, long id, DataObject obj) { DataObject emoji = obj.getObject("emoji"); - final int count = obj.getInt("count", -1); - final boolean me = obj.getBoolean("me"); + final int[] count = new int[]{ + obj.getInt("count", 0), // total + obj.getObject("count_details").getInt("normal"), + obj.getObject("count_details").getInt("burst"), + }; + final boolean[] me = new boolean[] { + obj.getBoolean("me"), // normal + obj.getBoolean("me_burst") // super + }; EmojiUnion emojiObj = createEmoji(emoji); return new MessageReaction(chan, emojiObj, id, me, count); diff --git a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmojiHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmojiHandler.java index 95f84e42e2..19d025d86d 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmojiHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionClearEmojiHandler.java @@ -69,7 +69,13 @@ protected Long handleInternally(DataObject content) DataObject emoji = content.getObject("emoji"); EmojiUnion reactionEmoji = EntityBuilder.createEmoji(emoji); - MessageReaction reaction = new MessageReaction(channel, reactionEmoji, messageId, false, 0); + // We don't know if it is a normal or super reaction + boolean[] self = new boolean[] { + false, + false + }; + + MessageReaction reaction = new MessageReaction(channel, reactionEmoji, messageId, self, null); getJDA().handleEvent(new MessageReactionRemoveEmojiEvent(getJDA(), responseNumber, messageId, channel, reaction)); 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 5e4178b425..9176c31d43 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/MessageReactionHandler.java @@ -158,7 +158,13 @@ protected Long handleInternally(DataObject content) // reaction remove has null name sometimes EmojiUnion rEmoji = EntityBuilder.createEmoji(emoji); - MessageReaction reaction = new MessageReaction(channel, rEmoji, messageId, userId == api.getSelfUser().getIdLong(), -1); + // We don't know if it is a normal or super reaction + boolean[] self = new boolean[] { + false, + false + }; + + MessageReaction reaction = new MessageReaction(channel, rEmoji, messageId, self, null); if (channel.getType() == ChannelType.PRIVATE) { From 8976a41b7938ce412790e596cacdef0c411d4dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sat, 21 Oct 2023 10:46:41 +0200 Subject: [PATCH 2/2] Update src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java --- .../java/net/dv8tion/jda/internal/entities/EntityBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java index 0c56e05e70..7b73b07aa6 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java @@ -1891,8 +1891,8 @@ public MessageReaction createMessageReaction(MessageChannel chan, long id, DataO DataObject emoji = obj.getObject("emoji"); final int[] count = new int[]{ obj.getInt("count", 0), // total - obj.getObject("count_details").getInt("normal"), - obj.getObject("count_details").getInt("burst"), + obj.optObject("count_details").map(o -> o.getInt("normal", 0)).orElse(0), + obj.optObject("count_details").map(o -> o.getInt("burst", 0)).orElse(0), }; final boolean[] me = new boolean[] { obj.getBoolean("me"), // normal