From 6ec43a7c9351254372445481c926ca5adce39e24 Mon Sep 17 00:00:00 2001 From: dkim19375 Date: Thu, 13 May 2021 18:32:33 -0400 Subject: [PATCH] rewrite in kotlin, UNTESTED --- build.gradle | 13 +- .../me/dkim19375/dkim19375jdautils/BotBase.kt | 68 +++++++ .../dkim19375jdautils/annotation/API.kt | 13 ++ .../dkim19375jdautils/command/Command.kt | 125 +++++++++++++ .../dkim19375jdautils/command/CommandArg.kt | 5 + .../dkim19375jdautils/command/CommandType.kt | 18 ++ .../dkim19375jdautils/command/HelpCommand.kt | 59 ++++++ .../data/MessageReceivedData.kt | 49 +---- .../dkim19375jdautils/embed/EmbedManager.kt | 170 ++++++++++-------- .../dkim19375jdautils/embed/EmbedUtils.kt | 50 +++--- .../dkim19375jdautils/event/CustomListener.kt | 95 ++++++++++ .../dkim19375jdautils/event/EventListener.kt | 157 ++++++++++++++++ .../files/PropertiesFile.java | 112 ------------ .../dkim19375jdautils/impl/EntryImpl.kt | 34 +--- .../util/CollectionFunctions.kt | 28 +++ 15 files changed, 709 insertions(+), 287 deletions(-) create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt delete mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/files/PropertiesFile.java create mode 100644 src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt diff --git a/build.gradle b/build.gradle index d5c29d9..3e155ae 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { - id 'java' + id 'org.jetbrains.kotlin.jvm' version '1.5.0' + id 'com.github.johnrengelman.shadow' version '6.0.0' } //noinspection GroovyUnusedAssignment @@ -7,13 +8,17 @@ sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 compileJava.options.encoding 'UTF-8' group 'me.dkim19375' -version '1.3.4' +version '2.0.0' + +compileKotlin.kotlinOptions.jvmTarget = '1.8' repositories { mavenCentral() - jcenter() + maven { url = 'https://m2.dv8tion.net/releases' } } dependencies { - compileOnly 'net.dv8tion:JDA:4.2.0_227' + compileOnly 'net.dv8tion:JDA:4.2.1_262' + api 'commons-io:commons-io:2.8.0' + api 'org.apache.commons:commons-lang3:3.12.0' } \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt b/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt new file mode 100644 index 0000000..8c49dc7 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt @@ -0,0 +1,68 @@ +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.event.CustomListener +import me.dkim19375.dkim19375jdautils.event.EventListener +import net.dv8tion.jda.api.JDA +import java.util.* +import kotlin.concurrent.thread +import kotlin.system.exitProcess + +@API +abstract class BotBase( + @API val jda: JDA, + val name: String, + val customListener: CustomListener = object : CustomListener() {} +) { + val commandTypes = setOf() + + @API + val commands = setOf() + + @API + val consoleCommands = mapOf Unit>() + private var started = false + + fun getPrefix(guild: Long): String = getPrefix(guild.toString()) + abstract fun getPrefix(guild: String): String + + @API + fun onStart(stopCommandEnabled: Boolean = true) { + if (started) { + return + } + started = true + jda.addEventListener(EventListener(this)) + Runtime.getRuntime().addShutdownHook(thread(false) { + if (jda.status != JDA.Status.SHUTDOWN && jda.status != JDA.Status.SHUTTING_DOWN) { + println("Stopping the bot!") + jda.shutdown() + println("Stopped") + } + }) + thread { + val scanner = Scanner(System.`in`) + while (scanner.hasNext()) { + val next = scanner.nextLine() + if (next.equals("stop", ignoreCase = true) && stopCommandEnabled) { + if (jda.status != JDA.Status.SHUTDOWN && jda.status != JDA.Status.SHUTTING_DOWN) { + println("Stopping the bot!") + jda.shutdown() + println("Stopped") + exitProcess(0) + } + continue + } + for ((cmd, action) in consoleCommands) { + if (next.startsWith(cmd, ignoreCase = true)) { + action(next) + } + } + } + } + } + + fun sendEvent(event: (Command) -> Unit) = commands.forEach(event) +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt b/src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt new file mode 100644 index 0000000..02c339c --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/annotation/API.kt @@ -0,0 +1,13 @@ +package me.dkim19375.dkim19375jdautils.annotation + +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.FIELD, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FUNCTION, + AnnotationTarget.FILE, + AnnotationTarget.VALUE_PARAMETER +) +@API +annotation class API \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt b/src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt new file mode 100644 index 0000000..1e41acf --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt @@ -0,0 +1,125 @@ +package me.dkim19375.dkim19375jdautils.command + +import me.dkim19375.dkim19375jdautils.BotBase +import me.dkim19375.dkim19375jdautils.annotation.API +import me.dkim19375.dkim19375jdautils.embed.EmbedManager +import me.dkim19375.dkim19375jdautils.embed.EmbedUtils +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.entities.User +import net.dv8tion.jda.api.events.Event +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent +import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent +import java.awt.Color + +@API +abstract class Command(private val bot: BotBase) { + abstract val command: String + abstract val name: String + abstract val aliases: Set + abstract val description: String + abstract val arguments: Set + abstract val type: CommandType + abstract val minArgs: Int + open val permissions: Set = setOf() + open val whitelistUsers: Set = setOf() + + fun sendHelpUsage( + cmd: String, + event: Event, + command: Command = this + ) { + val user = when (event) { + is GuildMessageReceivedEvent -> event.author + is PrivateMessageReceivedEvent -> event.author + is MessageReceivedEvent -> event.author + else -> return + } + val member: Member? = (event as? GuildMessageReceivedEvent)?.member + val guild = when (event) { + is GuildMessageReceivedEvent -> event.guild + is MessageReceivedEvent -> event.guild + else -> return + } + val channel = when (event) { + is GuildMessageReceivedEvent -> event.channel + is PrivateMessageReceivedEvent -> event.channel + is MessageReceivedEvent -> event.channel + else -> return + } + if (!hasPermissions(user, member, channel as? GuildChannel)) { + return + } + val embedManager = EmbedManager("${bot.name} ${command.name}", Color.BLUE, cmd, user) + embedManager.embedBuilder.addField( + "Information:", + command.description.plus( + "\n**Prefix: ${bot.getPrefix(guild.idLong)}**" + ), false + ) + embedManager.embedBuilder.addField(EmbedUtils.getEmbedGroup("Aliases:", command.aliases)) + embedManager.embedBuilder.addField(EmbedUtils.getEmbedGroup("Arguments:", command.arguments.map { arg -> + "${arg.arg} - ${arg.description}" + })) + channel.sendMessage(embedManager.embedBuilder.build()).queue() + } + + @API + fun hasPermissions(user: User, member: Member? = null, channel: GuildChannel? = null): Boolean { + if (whitelistUsers.isNotEmpty() && !whitelistUsers.contains(user.idLong)) { + return false + } + member ?: return true + if (channel != null) { + return member.hasPermission(channel, permissions) + } + return member.hasPermission(permissions) + } + + open fun onMessageReceived( + message: String, + event: MessageReceivedEvent + ) { + } + + open fun onCommand( + cmd: String, + args: List, + prefix: String, + all: String, + event: MessageReceivedEvent + ) { + } + + open fun onGuildMessageReceived( + message: String, + event: GuildMessageReceivedEvent + ) { + } + + open fun onGuildCommand( + cmd: String, + args: List, + prefix: String, + all: String, + event: GuildMessageReceivedEvent + ) { + } + + open fun onPrivateMessageReceived( + message: String, + event: PrivateMessageReceivedEvent + ) { + } + + open fun onPrivateCommand( + cmd: String, + args: List, + prefix: String, + all: String, + event: PrivateMessageReceivedEvent + ) { + } +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt b/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt new file mode 100644 index 0000000..c1459e2 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandArg.kt @@ -0,0 +1,5 @@ +package me.dkim19375.dkim19375jdautils.command + +import net.dv8tion.jda.api.Permission + +data class CommandArg(val baseCommand: Command, val arg: String, val description: String, val permissions: Set = setOf()) \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt b/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt new file mode 100644 index 0000000..d52a14a --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/command/CommandType.kt @@ -0,0 +1,18 @@ +package me.dkim19375.dkim19375jdautils.command + +import me.dkim19375.dkim19375jdautils.BotBase +import org.apache.commons.lang3.StringUtils + +fun String.getCommandType(bot: BotBase): CommandType? { + for (type in bot.commandTypes) { + if (type.name.equals(this, ignoreCase = true)) { + return type + } + if (type.displayname.equals(this, ignoreCase = true)) { + return type + } + } + return null +} + +abstract class CommandType(val name: String, val displayname: String = StringUtils.capitalize(name.lowercase())) \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt b/src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt new file mode 100644 index 0000000..a305bd8 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/command/HelpCommand.kt @@ -0,0 +1,59 @@ +package me.dkim19375.dkim19375jdautils.command + +import me.dkim19375.dkim19375jdautils.BotBase +import me.dkim19375.dkim19375jdautils.annotation.API +import me.dkim19375.dkim19375jdautils.embed.EmbedManager +import me.dkim19375.dkim19375jdautils.embed.EmbedUtils +import me.dkim19375.dkim19375jdautils.util.getCommand +import me.dkim19375.dkim19375jdautils.util.getOfType +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent +import java.awt.Color + +@API +class HelpCommand(private val bot: BotBase) : Command(bot) { + override val command = "help" + override val name = "Help" + override val aliases = setOf() + override val description = "See the bot's commands" + override val arguments: Set + get() = bot.commandTypes.map { type -> + CommandArg( + this, + type.displayname.lowercase(), + "View commands in the ${type.displayname.lowercase()} category" + ) + }.toSet() + override val type = object : CommandType("OTHER", "Other") {} + override val minArgs = 1 + + override fun onGuildCommand( + cmd: String, + args: List, + prefix: String, + all: String, + event: GuildMessageReceivedEvent + ) { + val type = args[0].getCommandType(bot) + if (type == null) { + val command = args[0].getCommand(bot) + if (command == null) { + sendHelpUsage(cmd, event) + return + } + sendHelpUsage(cmd, event, command) + return + } + val embedManager = EmbedManager("UniG0 $name: ${type.displayname}", Color.BLUE, cmd, event.author) + embedManager.embedBuilder.addField( + "TIP:", "Do ${bot.getPrefix(event.guild.id)}help " + + "to view information about a specific command!", false + ) + embedManager.embedBuilder.addField("Information:", "Commands in the ${type.displayname} category", false) + embedManager.embedBuilder.addField( + EmbedUtils.getEmbedGroup("Commands - ${type.displayname}:", bot.commands.getOfType(type).map { c -> + "${c.command} - ${c.description}" + }) + ) + event.channel.sendMessage(embedManager.embedBuilder.build()).queue() + } +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt b/src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt index 48164bd..5110597 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt +++ b/src/main/java/me/dkim19375/dkim19375jdautils/data/MessageReceivedData.kt @@ -1,42 +1,11 @@ -package me.dkim19375.dkim19375jdautils.holders; +package me.dkim19375.dkim19375jdautils.data -import org.jetbrains.annotations.NotNull; +import me.dkim19375.dkim19375jdautils.annotation.API -public class MessageReceivedHolder { - // (String command, String[] args, String prefix, String all) - @NotNull - private final String command; - @NotNull - private final String[] args; - @NotNull - private final String prefix; - @NotNull - private final String all; - - public MessageReceivedHolder(@NotNull String command, @NotNull String[] args, @NotNull String prefix, @NotNull String all) { - this.command = command; - this.args = args; - this.prefix = prefix; - this.all = all; - } - - @NotNull - public String getCommand() { - return command; - } - - @NotNull - public String[] getArgs() { - return args; - } - - @NotNull - public String getPrefix() { - return prefix; - } - - @NotNull - public String getAll() { - return all; - } -} \ No newline at end of file +@API +class MessageReceivedData( + val command: String, + val args: List, + val prefix: String, + val all: String +) \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt b/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt index 4790f7d..46bae8a 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt +++ b/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedManager.kt @@ -1,113 +1,125 @@ -package me.dkim19375.dkim19375jdautils.embeds; - -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.User; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.time.Instant; -import java.time.temporal.TemporalAccessor; - -public class EmbedManager { - @NotNull - private final EmbedBuilder embedBuilder = new EmbedBuilder(); - - public EmbedManager(final @Nullable String heading, final @Nullable String headingIcon, final @Nullable Color color, - final @Nullable String cmd, - final @Nullable String title, final @Nullable String titleURL, - final @Nullable CharSequence description, final @Nullable String footerIconURL, final @Nullable String image, - final @Nullable String thumbnail) { - embedBuilder.setAuthor(heading, null, headingIcon); - embedBuilder.setTimestamp(Instant.now()); - embedBuilder.setColor(color); - embedBuilder.setFooter(cmd, footerIconURL); - embedBuilder.setDescription(description); - embedBuilder.setImage(image); - embedBuilder.setThumbnail(thumbnail); - embedBuilder.setTitle(title, titleURL); +package me.dkim19375.dkim19375jdautils.embed + +import me.dkim19375.dkim19375jdautils.annotation.API +import net.dv8tion.jda.api.EmbedBuilder +import net.dv8tion.jda.api.entities.User +import java.awt.Color +import java.time.Instant +import java.time.temporal.TemporalAccessor + +@API +class EmbedManager { + @API + val embedBuilder = EmbedBuilder() + + @API + constructor( + heading: String? = null, headingIcon: String? = null, color: Color? = null, + cmd: String? = null, + title: String? = null, titleURL: String? = null, + description: CharSequence? = null, footerIconURL: String? = null, image: String? = null, + thumbnail: String? = null + ) { + embedBuilder.setAuthor(heading, null, headingIcon) + embedBuilder.setTimestamp(Instant.now()) + embedBuilder.setColor(color) + embedBuilder.setFooter(cmd, footerIconURL) + embedBuilder.setDescription(description) + embedBuilder.setImage(image) + embedBuilder.setThumbnail(thumbnail) + embedBuilder.setTitle(title, titleURL) } - public EmbedManager(final @Nullable String title, final @Nullable Color color, final @Nullable String cmd, - final @Nullable User user) { + @API + constructor( + title: String? = null, color: Color? = null, cmd: String? = null, + user: User? = null + ) { if (user != null) { - embedBuilder.setAuthor(user.getAsTag(), null, user.getAvatarUrl()); + embedBuilder.setAuthor(user.asTag, null, user.avatarUrl) } - embedBuilder.setTimestamp(Instant.now()); - embedBuilder.setColor(color); - embedBuilder.setFooter(cmd); - embedBuilder.setTitle(title); - } - - @NotNull - public EmbedBuilder getEmbedBuilder() { - return embedBuilder; + embedBuilder.setTimestamp(Instant.now()) + embedBuilder.setColor(color) + embedBuilder.setFooter(cmd) + embedBuilder.setTitle(title) } - public void setUser(@Nullable final User user) { + @API + fun setUser(user: User?) { if (user == null) { - embedBuilder.setAuthor(null); - return; + embedBuilder.setAuthor(null) + return } - embedBuilder.setAuthor(user.getName() + "#" + user.getDiscriminator()); + embedBuilder.setAuthor(user.name + "#" + user.discriminator) } - public void setTimeStamp(@Nullable final TemporalAccessor temporalAccessor) { - embedBuilder.setTimestamp(temporalAccessor); + @API + fun setTimeStamp(temporalAccessor: TemporalAccessor?) { + embedBuilder.setTimestamp(temporalAccessor) } - public void setColor(@Nullable final Color color) { - embedBuilder.setColor(color); + @API + fun setColor(color: Color?) { + embedBuilder.setColor(color) } - public void setFooter(@Nullable final String footer) { - embedBuilder.setFooter(footer); + @API + fun setFooter(footer: String?) { + embedBuilder.setFooter(footer) } - public void setFooter(@Nullable final String footer, @Nullable final String footerURL) { - embedBuilder.setFooter(footer, footerURL); + @API + fun setFooter(footer: String?, footerURL: String?) { + embedBuilder.setFooter(footer, footerURL) } - public void setDescription(@Nullable final CharSequence description) { - embedBuilder.setDescription(description); + @API + fun setDescription(description: CharSequence?) { + embedBuilder.setDescription(description) } - public void setImage(@Nullable final String imageUrl) { - embedBuilder.setImage(imageUrl); + @API + fun setImage(imageUrl: String?) { + embedBuilder.setImage(imageUrl) } - public void setThumbnail(@Nullable final String imageUrl) { - embedBuilder.setThumbnail(imageUrl); + @API + fun setThumbnail(imageUrl: String?) { + embedBuilder.setThumbnail(imageUrl) } - public void setTitle(@Nullable final String title) { - embedBuilder.setTitle(title); + @API + fun setTitle(title: String?) { + embedBuilder.setTitle(title) } - public void setTitle(@Nullable final String title, @Nullable final String titleUrl) { - embedBuilder.setTitle(title, titleUrl); + @API + fun setTitle(title: String?, titleUrl: String?) { + embedBuilder.setTitle(title, titleUrl) } - public void setEmbedBuilder(@NotNull final EmbedBuilder embedBuilder) { - this.embedBuilder.clear(); - final MessageEmbed messageEmbed = embedBuilder.build(); - this.embedBuilder.setDescription(messageEmbed.getDescription()); - this.embedBuilder.setTitle(messageEmbed.getTitle(), messageEmbed.getUrl()); - this.embedBuilder.setTimestamp(messageEmbed.getTimestamp()); - this.embedBuilder.setColor(messageEmbed.getColor()); - if (messageEmbed.getThumbnail() != null) { - this.embedBuilder.setThumbnail(messageEmbed.getThumbnail().getUrl()); + @API + fun setEmbedBuilder(embedBuilder: EmbedBuilder) { + this.embedBuilder.clear() + val messageEmbed = embedBuilder.build() + this.embedBuilder.setDescription(messageEmbed.description) + this.embedBuilder.setTitle(messageEmbed.title, messageEmbed.url) + this.embedBuilder.setTimestamp(messageEmbed.timestamp) + this.embedBuilder.setColor(messageEmbed.color) + if (messageEmbed.thumbnail != null) { + this.embedBuilder.setThumbnail(messageEmbed.thumbnail?.url) } - if (messageEmbed.getAuthor() != null) { - this.embedBuilder.setAuthor(messageEmbed.getAuthor().getName(), messageEmbed.getAuthor().getUrl(), messageEmbed.getAuthor().getIconUrl()); + if (messageEmbed.author != null) { + this.embedBuilder.setAuthor( + messageEmbed.author?.name, messageEmbed.author?.url, messageEmbed.author?.iconUrl + ) } - if (messageEmbed.getFooter() != null) { - this.embedBuilder.setFooter(messageEmbed.getFooter().getText(), messageEmbed.getFooter().getIconUrl()); + if (messageEmbed.footer != null) { + this.embedBuilder.setFooter(messageEmbed.footer?.text, messageEmbed.footer?.iconUrl) } - if (messageEmbed.getImage() != null) { - this.embedBuilder.setImage(messageEmbed.getImage().getUrl()); + if (messageEmbed.image != null) { + this.embedBuilder.setImage(messageEmbed.image?.url) } - this.embedBuilder.getFields().addAll(messageEmbed.getFields()); + this.embedBuilder.fields.addAll(messageEmbed.fields) } } \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt b/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt index 9cc6b84..233a22d 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt +++ b/src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt @@ -1,38 +1,36 @@ -package me.dkim19375.dkim19375jdautils.embeds; +package me.dkim19375.dkim19375jdautils.embed -import net.dv8tion.jda.api.entities.MessageEmbed; -import org.jetbrains.annotations.NotNull; +import me.dkim19375.dkim19375jdautils.annotation.API +import net.dv8tion.jda.api.entities.MessageEmbed -import java.util.*; - -public class EmbedUtils { - @NotNull - public static Set getEmbedGroups(final @NotNull Map<@NotNull String, ? extends Collection<@NotNull String>> groups) { - final Set fields = new HashSet<>(); - for (Map.Entry> group : groups.entrySet()) { - fields.add(getEmbedGroup(group)); +@API +object EmbedUtils { + @API + fun getEmbedGroups(groups: Map>): Set { + val fields: MutableSet = mutableSetOf() + for (group in groups.entries) { + fields.add(getEmbedGroup(group.key, group.value)) } - return fields; + return fields } - private static String combineStrings(String first, String second) { - return first + second; + private fun combineStrings(first: String, second: String): String { + return first + second } - @NotNull - public static MessageEmbed.Field getEmbedGroup(@NotNull final Map.Entry<@NotNull String, ? extends Collection<@NotNull String>> group) { - final String name = group.getKey(); - String value = "```\n- "; - int i = 1; - for (String string : group.getValue()) { - if (i == group.getValue().size()) { - value = combineStrings(value, string); + @API + fun getEmbedGroup(name: String, values: Collection): MessageEmbed.Field { + var value = "```\n- " + var i = 1 + for (string in values) { + value = if (i == values.size) { + combineStrings(value, string) } else { - value = combineStrings(value, string + "\n- "); + combineStrings(value, "$string\n- ") } - i++; + i++ } - value = combineStrings(value, "```"); - return new MessageEmbed.Field(name, value, true); + value = combineStrings(value, "```") + return MessageEmbed.Field(name, value, true) } } \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt b/src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt new file mode 100644 index 0000000..7a98957 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/event/CustomListener.kt @@ -0,0 +1,95 @@ +package me.dkim19375.dkim19375jdautils.event + +import me.dkim19375.dkim19375jdautils.annotation.API +import me.dkim19375.dkim19375jdautils.command.Command +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.MessageReceivedEvent +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent +import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent + +abstract class CustomListener { + @API + val antiBot: Boolean = true + + @API + fun onMessageReceived(event: MessageReceivedEvent): Boolean = true + @API + fun onGuildMessageReceived(event: GuildMessageReceivedEvent): Boolean = true + @API + fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent): Boolean = true + @API + fun isValid( + command: Command, + cmd: String, + args: List, + member: Member?, + user: User, + guild: Guild?, + message: Message, + channel: MessageChannel, + event: Event + ): Boolean { + if (!cmd.equals(command.command, ignoreCase = true)) { + return false + } + if (user.isBot && antiBot) { + return false + } + member?.let { + if (channel is GuildChannel) { + if (member.hasPermission(channel, command.permissions)) { + return@let + } + } else if (member.hasPermission(command.permissions)) { + return@let + } + if (event !is MessageReceivedEvent) { + channel.sendMessage( + "You do not have permission! (Required permission${if (command.permissions.size <= 1) "" else "s"}: ${ + command.permissions.joinToString( + ", ", transform = Permission::getName + ) + })" + ).queue() + } + return false + } + if (args.size < command.minArgs) { + when (event) { + is PrivateMessageReceivedEvent -> command.sendHelpUsage(cmd, event) + is GuildMessageReceivedEvent -> command.sendHelpUsage(cmd, event) + } + return false + } + return true + } + fun isValid( + command: Command, + cmd: String, + args: List, + event: GuildMessageReceivedEvent + ): Boolean = + isValid(command, cmd, args, event.member, event.author, event.guild, event.message, event.channel, event) + + fun isValid( + command: Command, + cmd: String, + args: List, + event: MessageReceivedEvent + ): Boolean = isValid( + command, cmd, args, event.member, event.author, try { + event.guild + } catch (_: IllegalStateException) { + null + }, event.message, event.channel, event + ) + + fun isValid( + command: Command, + cmd: String, + args: List, + event: PrivateMessageReceivedEvent + ): Boolean = isValid(command, cmd, args, null, event.author, null, event.message, event.channel, event) +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt b/src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt new file mode 100644 index 0000000..aad9467 --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/event/EventListener.kt @@ -0,0 +1,157 @@ +package me.dkim19375.dkim19375jdautils.event + +import me.dkim19375.dkim19375jdautils.BotBase +import me.dkim19375.dkim19375jdautils.command.Command +import me.dkim19375.dkim19375jdautils.data.MessageReceivedData +import net.dv8tion.jda.api.events.message.MessageReceivedEvent +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent +import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent +import net.dv8tion.jda.api.hooks.ListenerAdapter + +class EventListener(private val bot: BotBase) : ListenerAdapter() { + private fun getMessage(message: String, serverId: String?): MessageReceivedData? { + if (serverId == null) { + if (!message.startsWith(bot.jda.selfUser.asMention.replaceFirst("@".toRegex(), "@!"))) { + return null + } + } + val prefix: String = if (serverId == null) bot.jda.selfUser.asMention.replaceFirst("@".toRegex(), "@!") + else if (message.startsWith(bot.jda.selfUser.asMention.replaceFirst("@".toRegex(), "@!"))) { + bot.jda.selfUser.asMention.replaceFirst("@".toRegex(), "@!") + } else { + if (message.startsWith(bot.getPrefix(serverId), ignoreCase = true)) { + bot.getPrefix(serverId) + } else { + return null + } + } + if (message.length <= prefix.length) { + return null + } + var command = message + command = command.substring(prefix.length) + command = command.trim { it <= ' ' } + val allArray = command.split(" ").toTypedArray() + command = command.split(" ").toTypedArray()[0] + val argsList = mutableListOf() + var first = true + for (s in allArray) { + if (!first) { + argsList.add(s) + } + first = false + } + return MessageReceivedData(command, argsList, prefix, message) + } + + override fun onMessageReceived(event: MessageReceivedEvent) { + if (!bot.customListener.onMessageReceived(event)) { + return + } + try { + bot.sendEvent { c -> c.onMessageReceived(event.message.contentRaw, event) } + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + val msg = getMessage( + event.message.contentRaw, try { + event.guild + } catch (_: IllegalStateException) { + null + }?.id + ) + if (msg != null) { + bot.sendEvent { c -> + if (!isValid(c, msg.command, msg.args.toList(), event)) { + return@sendEvent + } + try { + c.onCommand(msg.command, msg.args.toList(), msg.prefix, msg.all, event) + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + } + } + } + + override fun onGuildMessageReceived(event: GuildMessageReceivedEvent) { + if (!bot.customListener.onGuildMessageReceived(event)) { + return + } + try { + bot.sendEvent { c -> c.onGuildMessageReceived(event.message.contentRaw, event) } + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + val msg = getMessage(event.message.contentRaw, event.guild.id) + if (msg != null) { + bot.sendEvent { c -> + if (!isValid(c, msg.command, msg.args.toList(), event)) { + return@sendEvent + } + try { + c.onGuildCommand(msg.command, msg.args.toList(), msg.prefix, msg.all, event) + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + } + } + } + + override fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent) { + if (!bot.customListener.onPrivateMessageReceived(event)) { + return + } + try { + bot.sendEvent { c -> c.onPrivateMessageReceived(event.message.contentRaw, event) } + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + val msg = getMessage(event.message.contentRaw, null) + if (msg != null) { + try { + bot.sendEvent { c -> + if (!isValid(c, msg.command, msg.args.toList(), event)) { + return@sendEvent + } + try { + c.onPrivateCommand(msg.command, msg.args.toList(), msg.prefix, msg.all, event) + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + } + } catch (e: Exception) { + e.printStackTrace() + event.channel.sendMessage("An internal error has occurred!").queue() + } + } + } + + private fun isValid( + command: Command, + cmd: String, + args: List, + event: GuildMessageReceivedEvent + ): Boolean = bot.customListener.isValid(command, cmd, args, event) + + private fun isValid( + command: Command, + cmd: String, + args: List, + event: MessageReceivedEvent + ): Boolean = + bot.customListener.isValid(command, cmd, args, event) + + private fun isValid( + command: Command, + cmd: String, + args: List, + event: PrivateMessageReceivedEvent + ): Boolean = bot.customListener.isValid(command, cmd, args, event) +} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/files/PropertiesFile.java b/src/main/java/me/dkim19375/dkim19375jdautils/files/PropertiesFile.java deleted file mode 100644 index 6c6c302..0000000 --- a/src/main/java/me/dkim19375/dkim19375jdautils/files/PropertiesFile.java +++ /dev/null @@ -1,112 +0,0 @@ -package me.dkim19375.dkim19375jdautils.files; - -import org.jetbrains.annotations.NotNull; - -import java.io.*; -import java.util.Properties; - -public class PropertiesFile { - @NotNull - private final String fileName; - private Properties properties; - - public PropertiesFile(@NotNull String fileName) { - this.fileName = fileName; - } - - public boolean createFile(boolean load) { - try (InputStream input = PropertiesFile.class.getClassLoader().getResourceAsStream(fileName)) { - properties = new Properties(); - if (input == null) { - try (InputStream inputStream = new FileInputStream(fileName)) { - if (load) { - properties.load(inputStream); - } - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - if (load) { - properties.load(input); - } - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - public boolean createFile() { - return createFile(false); - } - - public boolean loadFile(@NotNull InputStream stream) { - try { - properties.load(stream); - } catch (IOException exception) { - exception.printStackTrace(); - return false; - } - return true; - } - - public boolean loadFile() { - if (properties == null) { - return false; - } - try (InputStream inputStream = new FileInputStream(fileName)) { - properties.load(inputStream); - } catch (FileNotFoundException e) { - createFile(true); - try { - properties.load(new FileInputStream(fileName)); - } catch (IOException exception) { - exception.printStackTrace(); - return false; - } - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - @NotNull - public Properties getProperties() { - return properties; - } - - public boolean saveFile() { - try (OutputStream output = new FileOutputStream(fileName)) { - properties.store(output, null); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - public boolean saveFile(boolean create) { - try (OutputStream output = new FileOutputStream(fileName)) { - properties.store(output, null); - } catch (FileNotFoundException e) { - if (createFile(true) && create) { - try (OutputStream output = new FileOutputStream(fileName)) { - properties.store(output, null); - } catch (IOException ex) { - ex.printStackTrace(); - return false; - } - return true; - } - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } -} \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt b/src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt index 27fcce5..89c87b3 100644 --- a/src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt +++ b/src/main/java/me/dkim19375/dkim19375jdautils/impl/EntryImpl.kt @@ -1,30 +1,12 @@ -package me.dkim19375.dkim19375jdautils.impl; +package me.dkim19375.dkim19375jdautils.impl -import java.util.Map; +import me.dkim19375.dkim19375jdautils.annotation.API -public class EntryImpl implements Map.Entry { - private final K key; - private V value; - - public EntryImpl(final K key, final V value) { - this.key = key; - this.value = value; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return value; - } - - @Override - public V setValue(V value) { - V oldValue = this.value; - this.value = value; - return oldValue; +@API +class EntryImpl(override val key: K, override var value: V) : MutableMap.MutableEntry { + override fun setValue(newValue: V): V { + val oldValue = this.value + this.value = newValue + return oldValue } } \ No newline at end of file diff --git a/src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt b/src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt new file mode 100644 index 0000000..977128b --- /dev/null +++ b/src/main/java/me/dkim19375/dkim19375jdautils/util/CollectionFunctions.kt @@ -0,0 +1,28 @@ +package me.dkim19375.dkim19375jdautils.util + +import me.dkim19375.dkim19375jdautils.BotBase +import me.dkim19375.dkim19375jdautils.command.Command +import me.dkim19375.dkim19375jdautils.command.CommandType + +fun Iterable.containsIgnoreCase(find: String): Boolean = getIgnoreCase(find) != null +fun Iterable.getIgnoreCase(find: String): String? = firstOrNull { it.equals(find, ignoreCase = true) } + +fun String.getCommand(bot: BotBase): Command? = bot.commands.getCommand(this) + +fun Set.getCommand(name: String): Command? { + return firstOrNull { cmd -> + cmd.name.equals(name, ignoreCase = true) + || cmd.command.equals(name, ignoreCase = true) + || cmd.aliases.containsIgnoreCase(name) + } +} + +fun Set.getOfType(type: CommandType): Set { + val ofType = mutableSetOf() + for (cmd in this) { + if (cmd.type == type) { + ofType.add(cmd) + } + } + return ofType +} \ No newline at end of file