diff --git a/README.md b/README.md new file mode 100644 index 0000000..10aa463 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# dkim19375JDAUtils +A kotlin library for JDA to help to make discord bots easier! + +**WARNING! UPDATES MAY INCLUDE API BREAKING CHANGES! +THE API IS STILL VERY NEW, RESULTING IN FREQUENT CHANGES** + +### An example of using this library is with my bot UniG0 - https://github.com/dkim19375/UniG0 + +**NOTE: This might not be up-to-date, if these code snippets don't +work, please notify me!** + +## Adding the dependency +```groovy +repositories { + maven { url = 'https://jitpack.io' } +} +dependencies { + implementation 'com.github.dkim19375:dkim19375JDAUtils:VERSION' +} +``` + +## Setting up the bot +A class, that holds information such as the commands, needs to be +created. It extends `me.dkim19375.dkim19375JDAUtils.BotBase`. +To start the bot, you call BotBase#onStart. +It is recommended to make this your main class. +```kotlin +import me.dkim19375.dkim19375jdautils.BotBase + +class Bot : BotBase() { + override val name = "Bot-Name" + override val token = "token-here" + + init { + onStart() + } + + override fun getPrefix(guild: String): String { + return "!" + } +} +``` +Now, you can simply run the bot, invite the bot to a server, +then run `!help`! \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/BotBase.kt similarity index 93% rename from src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/BotBase.kt index 3ff97ca..ba98e46 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt +++ b/src/main/kotlin/me/dkim19375/dkim19375jdautils/BotBase.kt @@ -2,7 +2,8 @@ package me.dkim19375.dkim19375jdautils import me.dkim19375.dkim19375jdautils.annotation.API import me.dkim19375.dkim19375jdautils.command.Command -import me.dkim19375.dkim19375jdautils.command.CommandType +import me.dkim19375.dkim19375jdautils.command.HelpCommand +import me.dkim19375.dkim19375jdautils.command.OTHER_TYPE import me.dkim19375.dkim19375jdautils.event.CustomListener import me.dkim19375.dkim19375jdautils.event.EventListener import me.dkim19375.dkim19375jdautils.managers.SpecialEventsManager @@ -19,6 +20,7 @@ import kotlin.system.exitProcess * @constructor Create a bot base, should be the main class of your bot */ @API +@Suppress("LeakingThis") abstract class BotBase { abstract val name: String abstract val token: String @@ -26,10 +28,9 @@ abstract class BotBase { open val intents = mutableSetOf(GatewayIntent.GUILD_MESSAGE_REACTIONS, GatewayIntent.DIRECT_MESSAGE_REACTIONS) lateinit var jda: JDA - val commandTypes = mutableSetOf() - val commands = mutableSetOf() + val commandTypes = mutableSetOf(OTHER_TYPE) + val commands = mutableSetOf(HelpCommand(this)) - @Suppress("LeakingThis") @API val eventsManager: SpecialEventsManager = SpecialEventsManager(this) diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/annotation/API.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/annotation/API.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/command/Command.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/command/Command.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/command/CommandArg.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/command/CommandArg.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/command/CommandType.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/command/CommandType.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/data/Whitelist.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/data/Whitelist.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/data/Whitelist.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/data/Whitelist.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/event/CustomListener.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/event/CustomListener.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/event/EventListener.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/event/EventListener.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt similarity index 88% rename from src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt index fe3e809..73a67dc 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt +++ b/src/main/kotlin/me/dkim19375/dkim19375jdautils/managers/SpecialEventsManager.kt @@ -3,9 +3,7 @@ package me.dkim19375.dkim19375jdautils.managers import me.dkim19375.dkim19375jdautils.BotBase import me.dkim19375.dkim19375jdautils.annotation.API import me.dkim19375.dkim19375jdautils.data.Whitelist -import me.dkim19375.dkim19375jdautils.util.EventType -import me.dkim19375.dkim19375jdautils.util.getMessageId -import me.dkim19375.dkim19375jdautils.util.getUserId +import me.dkim19375.dkim19375jdautils.util.* import net.dv8tion.jda.api.entities.* import net.dv8tion.jda.api.events.Event import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent @@ -13,6 +11,7 @@ import net.dv8tion.jda.api.events.message.priv.react.PrivateMessageReactionAddEv import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent import net.dv8tion.jda.api.hooks.ListenerAdapter import net.dv8tion.jda.api.requests.RestAction +import java.util.* import java.util.concurrent.CompletableFuture import java.util.concurrent.Executors import java.util.concurrent.Future @@ -29,20 +28,45 @@ import kotlin.reflect.KClass open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { private val executor = Executors.newSingleThreadExecutor() - private val events = mutableListOf<(Event) -> Future>>() - private val singleEvents = mutableMapOf Future>>>() + @API + val events = mutableMapOf Future>>() + + @API + val singleEvents = mutableMapOf Future>>>() 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) + @API + fun getTask(uuid: UUID): ((Event) -> Future>)? { + events[uuid]?.let { + return it + } + for (map in singleEvents.values) { + for ((newUUID, event) in map) { + if (newUUID == uuid) { + return event + } + } + } + return null + } + + @API + @Synchronized + fun removeTask(uuid: UUID) { + events.remove(uuid) + singleEvents.forEach { (_, map) -> map.remove(uuid) } + } + @Synchronized protected open fun onEvent(@Suppress("SameParameterValue") type: Type, event: Event) { events.toList().forEach { e -> executor.submit { - val result = e(event).get() + val result = e.second(event).get() if (result.second && result.first) { - events.removeIf { it === e } + events.removeIf { uuid, _ -> uuid == e.first } } } } @@ -52,13 +76,13 @@ open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { } for (expression in list.toList()) { executor.submit { - val result = expression(event).get() + val result = expression.second(event).get() if (result.first) { - list.removeIf { it === expression } + list.removeIf { uuid, _ -> uuid == expression.first } } } } - if (singleEvents.getOrDefault(otherType, mutableListOf()).isEmpty()) { + if (singleEvents.getOrDefault(otherType, mutableMapOf()).isEmpty()) { singleEvents.remove(otherType) } } @@ -92,7 +116,7 @@ open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { open fun onReactionAdd( permanent: Boolean, eventType: EventType, - action: (Event, Guild?, MessageReaction.ReactionEmote, MessageChannel, User, Message, Member?) -> Boolean, + action: (Event, Guild?, MessageReaction.ReactionEmote, MessageChannel, User, Message, Member?, UUID) -> Boolean, requiredMessage: Long = 0, requiredChannel: Long = 0, requiredGuild: Long = 0, @@ -102,8 +126,10 @@ open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { removeSelfIfNoPerms: Boolean = false, reaction: MessageReaction.ReactionEmote? = null, debug: Boolean = false - ) { - @Suppress("DuplicatedCode") val actionVar: (Event) -> Future> = actionLabel@{ event -> + ): UUID { + val combined = events.keys.plus(singleEvents.values.map { a -> a.keys }.combine()) + val uuid = combined.getRandomUUID() + val actionVar: (Event) -> Future> = actionLabel@{ event -> val future = CompletableFuture>() if (debug) { println("called ------------") @@ -226,7 +252,7 @@ open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { future.complete( Pair( first = true, - second = !action(event, guild, emoji, channel, user, msg, member) + second = !action(event, guild, emoji, channel, user, msg, member, uuid) ) ) return@removeNoPermsLabel true @@ -276,11 +302,11 @@ open class SpecialEventsManager(private val bot: BotBase) : ListenerAdapter() { println("added to variables") } if (permanent) { - events.add(actionVar) - return + events[uuid] = actionVar + return uuid } - singleEvents.getOrPut(Type.REACTION_ADD) - { mutableListOf() }.add(actionVar) + singleEvents.getOrPut(Type.REACTION_ADD) { mutableMapOf() }[uuid] = actionVar + return uuid } /** diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt similarity index 64% rename from src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt index bbd9cab..6679303 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt +++ b/src/main/kotlin/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt @@ -3,6 +3,7 @@ package me.dkim19375.dkim19375jdautils.util import me.dkim19375.dkim19375jdautils.BotBase import me.dkim19375.dkim19375jdautils.command.Command import me.dkim19375.dkim19375jdautils.command.CommandType +import java.util.* fun Iterable.containsIgnoreCase(find: String): Boolean = getIgnoreCase(find) != null fun Iterable.getIgnoreCase(find: String): String? = firstOrNull { it.equals(find, ignoreCase = true) } @@ -22,4 +23,29 @@ fun Set.getOfType(type: CommandType): Set { } } return ofType +} +fun MutableMap.removeIf(filter: (K, V) -> Boolean) { + for ((k, v) in toMap()) { + if (filter(k, v)) { + remove(k) + } + } +} + +fun Collection.getRandomUUID(): UUID { + while (true) { + val uuid = UUID.randomUUID() + if (contains(uuid)) { + continue + } + return uuid + } +} + +fun Collection>.combine(): List { + val new = mutableListOf() + for (item in this) { + new.addAll(item) + } + return new } \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/util/EventFunctions.kt diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt b/src/main/kotlin/me/dkim19375/dkim19375jdautils/util/EventType.kt similarity index 100% rename from src/main/java/me/dkim19375/dkim19375jdautils/util/EventType.kt rename to src/main/kotlin/me/dkim19375/dkim19375jdautils/util/EventType.kt