From 06f7d2707a87bc0ca02a9744038c0e82e9479485 Mon Sep 17 00:00:00 2001 From: dkim19375 Date: Sun, 16 May 2021 09:43:47 -0400 Subject: [PATCH] Added SpecialEventsManager, untested --- build.gradle | 2 +- .../me/dkim19375/dkim19375jdautils/BotBase.kt | 12 +- .../managers/SpecialEventsManager.kt | 133 ++++++++++++++++++ .../dkim19375jdautils/util/EventFunctions.kt | 47 +++++++ .../dkim19375jdautils/util/EventType.kt | 7 + 5 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt diff --git a/build.gradle b/build.gradle index 00607bd..dc0f06c 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 compileJava.options.encoding 'UTF-8' group 'me.dkim19375' -version '2.1.0' +version '2.2.0' //noinspection GrUnresolvedAccess compileKotlin.kotlinOptions.jvmTarget = '1.8' diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt b/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt index 129885e..1071b16 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt +++ b/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt @@ -5,8 +5,10 @@ import me.dkim19375.dkim19375jdautils.command.Command import me.dkim19375.dkim19375jdautils.command.CommandType import me.dkim19375.dkim19375jdautils.event.CustomListener import me.dkim19375.dkim19375jdautils.event.EventListener +import me.dkim19375.dkim19375jdautils.managers.SpecialEventsManager import net.dv8tion.jda.api.JDA import net.dv8tion.jda.api.JDABuilder +import net.dv8tion.jda.api.requests.GatewayIntent import java.util.* import kotlin.concurrent.thread import kotlin.system.exitProcess @@ -21,12 +23,16 @@ abstract class BotBase { abstract val name: String abstract val token: String open val customListener: CustomListener = object : CustomListener() {} + open val intents = mutableSetOf(GatewayIntent.GUILD_MESSAGE_REACTIONS, GatewayIntent.DIRECT_MESSAGE_REACTIONS) - @API lateinit var jda: JDA val commandTypes = mutableSetOf() - @API val commands = mutableSetOf() + + @Suppress("LeakingThis") + @API + val eventsManager: SpecialEventsManager = SpecialEventsManager(this) + @API val consoleCommands = mutableMapOf Unit>() private var started = false @@ -54,9 +60,11 @@ abstract class BotBase { started = true println("Starting bot") val builder = JDABuilder.createDefault(token) + builder.enableIntents(intents) val jda = builder.build() this.jda = jda jda.addEventListener(EventListener(this)) + jda.addEventListener(SpecialEventsManager(this)) Runtime.getRuntime().addShutdownHook(thread(false) { if (jda.status != JDA.Status.SHUTDOWN && jda.status != JDA.Status.SHUTTING_DOWN) { println("Stopping the bot!") diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt b/src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt new file mode 100644 index 0000000..e1965f4 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt @@ -0,0 +1,133 @@ +package me.dkim19375.dkim19375jdautils.managers + +import me.dkim19375.dkim19375jdautils.BotBase +import me.dkim19375.dkim19375jdautils.annotation.API +import me.dkim19375.dkim19375jdautils.util.EventType +import me.dkim19375.dkim19375jdautils.util.getMessageId +import me.dkim19375.dkim19375jdautils.util.getUserId +import me.dkim19375.dkim19375jdautils.util.hasPermission +import net.dv8tion.jda.api.Permission +import net.dv8tion.jda.api.entities.* +import net.dv8tion.jda.api.events.Event +import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent +import net.dv8tion.jda.api.events.message.priv.react.PrivateMessageReactionAddEvent +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent +import net.dv8tion.jda.api.hooks.ListenerAdapter +import net.dv8tion.jda.api.requests.RestAction +import kotlin.reflect.KClass + +open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { + private val events = mutableListOf<(Event) -> Unit>() + private val singleEvents = mutableMapOf Unit>>() + + override fun onGuildMessageReactionAdd(event: GuildMessageReactionAddEvent) = onEvent(Type.REACTION_ADD, event) + override fun onPrivateMessageReactionAdd(event: PrivateMessageReactionAddEvent) = onEvent(Type.REACTION_ADD, event) + override fun onMessageReactionAdd(event: MessageReactionAddEvent) = onEvent(Type.REACTION_ADD, event) + + private fun onEvent(@Suppress("SameParameterValue") type: Type, event: Event) { + events.forEach { it(event) } + for ((otherType, list) in singleEvents.toMap()) { + if (otherType != type) { + continue + } + singleEvents.remove(otherType) + list.forEach { it(event) } + } + } + + @API + fun onReactionAdd( + permanent: Boolean, + eventType: EventType, + action: (Event, Guild?, MessageReaction.ReactionEmote, MessageChannel, User, Message, Member?) -> Unit, + requiredMessage: Long = 0, + requiredChannel: Long = 0, + requiredGuild: Long = 0, + whitelist: Set? = null, + requiredPerms: Set = emptySet(), + removeIfNoPerms: Boolean = false, + reaction: MessageReaction.ReactionEmote? = null, + ) { + val actionVar: (Event) -> Unit = action@{ event -> + val jda = event.jda + when (event) { + is GuildMessageReactionAddEvent -> if (eventType != EventType.GUILD) return@action + is MessageReactionAddEvent -> if (eventType != EventType.GENERIC) return@action + is PrivateMessageReactionAddEvent -> if (eventType != EventType.PRIVATE) return@action + } + val messageId: Long = event.getMessageId() ?: return@action + val userId: Long = event.getUserId() ?: return@action + val guild: Guild? = when (event) { + is GuildMessageReactionAddEvent -> event.guild + else -> null + } + val emoji: MessageReaction.ReactionEmote = when (event) { + is GuildMessageReactionAddEvent -> event.reactionEmote + is MessageReactionAddEvent -> event.reactionEmote + is PrivateMessageReactionAddEvent -> event.reactionEmote + else -> return@action + } + val channel = when (event) { + is GuildMessageReactionAddEvent -> event.channel + is MessageReactionAddEvent -> event.channel + is PrivateMessageReactionAddEvent -> event.channel + else -> return@action + } + if (requiredChannel != 0L && requiredChannel != channel.idLong) { + return@action + } + if (reaction != null) { + if (reaction.name != emoji.name) { + return@action + } + } + val retrievedMessage: RestAction = when (event) { + is GuildMessageReactionAddEvent -> event.retrieveMessage() + is MessageReactionAddEvent -> event.retrieveMessage() + is PrivateMessageReactionAddEvent -> event.channel.retrieveMessageById(event.messageIdLong) + else -> return@action + } + if (requiredGuild != guild?.idLong && (requiredGuild != 0L && guild != null)) { + return@action + } + if (requiredMessage != messageId && requiredMessage != 0L) { + return@action + } + retrievedMessage.queue message@{ msg -> + jda.retrieveUserById(userId).queue userQ@{ user -> + if (whitelist?.contains(userId) != false) { + if (!removeIfNoPerms) { + return@userQ + } + when { + emoji.isEmoji -> msg.removeReaction(emoji.emoji, user) + emoji.isEmote -> msg.removeReaction(emoji.emote, user) + } + return@userQ + } + guild?.retrieveMemberById(userId)?.queue memberQueue@{ member -> + if (!member.hasPermission(requiredPerms, channel as? GuildChannel)) { + return@memberQueue + } + action(event, guild, emoji, channel, user, msg, member) + } ?: action(event, guild, emoji, channel, user, msg, null) + } + } + } + if (permanent) { + events.add(actionVar) + return + } + singleEvents.getOrPut(Type.REACTION_ADD) { mutableListOf() }.add(actionVar) + } + + enum class Type(@API val classes: Set>) { + REACTION_ADD( + setOf( + MessageReactionAddEvent::class, + GuildMessageReactionAddEvent::class, + PrivateMessageReactionAddEvent::class + ) + ) + } +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt b/src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt new file mode 100644 index 0000000..773ff01 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt @@ -0,0 +1,47 @@ +package me.dkim19375.dkim19375jdautils.util + +import net.dv8tion.jda.api.Permission +import net.dv8tion.jda.api.entities.GuildChannel +import net.dv8tion.jda.api.entities.Member +import net.dv8tion.jda.api.events.Event +import net.dv8tion.jda.api.events.message.GenericMessageEvent +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.events.message.guild.GenericGuildMessageEvent +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent +import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent +import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent +import net.dv8tion.jda.api.events.message.priv.GenericPrivateMessageEvent +import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent +import net.dv8tion.jda.api.events.message.priv.react.PrivateMessageReactionAddEvent +import net.dv8tion.jda.api.events.message.priv.react.PrivateMessageReactionRemoveEvent +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent +import net.dv8tion.jda.api.events.message.react.MessageReactionRemoveEvent +import net.dv8tion.jda.api.events.user.GenericUserEvent + +fun Event.getUserId(): Long? = when (this) { + is GuildMessageReceivedEvent -> author.idLong + is MessageReceivedEvent -> author.idLong + is PrivateMessageReceivedEvent -> author.idLong + is GuildMessageReactionAddEvent -> userIdLong + is MessageReactionAddEvent -> userIdLong + is PrivateMessageReactionAddEvent -> userIdLong + is GuildMessageReactionRemoveEvent -> userIdLong + is MessageReactionRemoveEvent -> userIdLong + is PrivateMessageReactionRemoveEvent -> userIdLong + is GenericUserEvent -> user.idLong + else -> null +} + +fun Event.getMessageId(): Long? = when (this) { + is GenericGuildMessageEvent -> messageIdLong + is GenericMessageEvent -> messageIdLong + is GenericPrivateMessageEvent -> messageIdLong + else -> null +} + +fun Member.hasPermission(permissions: Collection, channel: GuildChannel? = null): Boolean { + if (channel != null) { + return hasPermission(channel, permissions) + } + return hasPermission(permissions) +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt b/src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt new file mode 100644 index 0000000..3957230 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt @@ -0,0 +1,7 @@ +package me.dkim19375.dkim19375jdautils.util + +enum class EventType { + PRIVATE, + GUILD, + GENERIC +} \ No newline at end of file