Skip to content

Commit

Permalink
Added SpecialEventsManager, untested
Browse files Browse the repository at this point in the history
  • Loading branch information
dkim19375 committed May 16, 2021
1 parent 709dd38 commit 06f7d27
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 3 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<CommandType>()
@API
val commands = mutableSetOf<Command>()

@Suppress("LeakingThis")
@API
val eventsManager: SpecialEventsManager = SpecialEventsManager(this)

@API
val consoleCommands = mutableMapOf<String, (String) -> Unit>()
private var started = false
Expand Down Expand Up @@ -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!")
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Type, MutableList<(Event) -> 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<Long>? = null,
requiredPerms: Set<Permission> = 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<Message> = 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<KClass<out Event>>) {
REACTION_ADD(
setOf(
MessageReactionAddEvent::class,
GuildMessageReactionAddEvent::class,
PrivateMessageReactionAddEvent::class
)
)
}
}
Original file line number Diff line number Diff line change
@@ -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<Permission>, channel: GuildChannel? = null): Boolean {
if (channel != null) {
return hasPermission(channel, permissions)
}
return hasPermission(permissions)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.dkim19375.dkim19375jdautils.util

enum class EventType {
PRIVATE,
GUILD,
GENERIC
}

0 comments on commit 06f7d27

Please sign in to comment.