Skip to content

Commit

Permalink
add perm checks and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dkim19375 committed May 14, 2021
1 parent f4f98cf commit 98cf4d4
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 60 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ compileJava.options.encoding 'UTF-8'
group 'me.dkim19375'
version '2.0.4'

//noinspection GrUnresolvedAccess
compileKotlin.kotlinOptions.jvmTarget = '1.8'

repositories {
Expand Down
32 changes: 26 additions & 6 deletions src/main/java/me/dkim19375/dkim19375jdautils/BotBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,41 @@ import java.util.*
import kotlin.concurrent.thread
import kotlin.system.exitProcess

/**
* Bot base
*
* @constructor Create a bot base, should be the main class of your bot
*/
@API
abstract class BotBase(
open val name: String,
open val token: String,
abstract class BotBase {
abstract val name: String
abstract val token: String
open val customListener: CustomListener = object : CustomListener() {}
) {

@API
lateinit var jda: JDA
val commandTypes = mutableSetOf<CommandType>()

@API
val commands = mutableSetOf<Command>()

@API
val consoleCommands = mutableMapOf<String, (String) -> Unit>()
private var started = false

/**
* @param guild The guild to get the prefix of
* @return The prefix
*/
fun getPrefix(guild: Long): String = getPrefix(guild.toString())

/**
* @param guild The guild to get the prefix of
* @return The prefix
*/
abstract fun getPrefix(guild: String): String

/**
* @param stopCommandEnabled True if the stop console command should be enabled, false if not
*/
@API
fun onStart(stopCommandEnabled: Boolean = true) {
if (started) {
Expand Down Expand Up @@ -71,5 +86,10 @@ abstract class BotBase(
}
}

/**
* The method which is called them a command is being sent to all of the [Command]s in [commands]
*
* @param event the event of the command
*/
open fun sendEvent(event: (Command) -> Unit) = commands.forEach(event)
}
76 changes: 74 additions & 2 deletions src/main/java/me/dkim19375/dkim19375jdautils/command/Command.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import java.awt.Color

/**
* The [Command] class - should be extended in every command class
*
* @property bot The [BotBase] of this bot
* @constructor Creates a [Command] that should be in [BotBase.commands]
*/
@API
abstract class Command(private val bot: BotBase) {
abstract val command: String
Expand All @@ -26,7 +32,14 @@ abstract class Command(private val bot: BotBase) {
open val permissions: Set<Permission> = setOf()
open val whitelistUsers: Set<Long> = setOf()

fun sendHelpUsage(
/**
* Send help usage
*
* @param cmd The command of the sent message
* @param event either [PrivateMessageReceivedEvent], [GuildMessageReceivedEvent], or [MessageReceivedEvent]
* @param command the [Command] to set the help message for
*/
open fun sendHelpUsage(
cmd: String,
event: Event,
command: Command = this
Expand Down Expand Up @@ -66,8 +79,16 @@ abstract class Command(private val bot: BotBase) {
channel.sendMessage(embedManager.embedBuilder.build()).queue()
}

/**
* Checks if a user has permissions to run this [Command]
*
* @param user The [User] who sent the command
* @param member The [Member] who sent the command, null if not in a guild
* @param channel the [GuildChannel] of where the command was set, null if not in a guild
* @return True if the user has permissions, false if not
*/
@API
fun hasPermissions(user: User, member: Member? = null, channel: GuildChannel? = null): Boolean {
open fun hasPermissions(user: User, member: Member? = null, channel: GuildChannel? = null): Boolean {
if (whitelistUsers.isNotEmpty() && !whitelistUsers.contains(user.idLong)) {
return false
}
Expand All @@ -78,12 +99,29 @@ abstract class Command(private val bot: BotBase) {
return member.hasPermission(permissions)
}

/**
* Called when a message was received
*
* Should not be used for general command handling
*
* @param message The message that the user sent
* @param event The [MessageReceivedEvent] of the sent message
*/
open fun onMessageReceived(
message: String,
event: MessageReceivedEvent
) {
}

/**
* On command
*
* @param cmd The command/alias
* @param args The args, for example: **!help fun 2** would be **{ "fun", "2" }**
* @param prefix The prefix of the command sent
* @param all The entire raw command **excluding** the prefix
* @param event The [MessageReceivedEvent]
*/
open fun onCommand(
cmd: String,
args: List<String>,
Expand All @@ -93,12 +131,29 @@ abstract class Command(private val bot: BotBase) {
) {
}

/**
* Called when a guild message was received
*
* Should not be used for general command handling
*
* @param message The message that the user sent
* @param event The [GuildMessageReceivedEvent] of the sent message
*/
open fun onGuildMessageReceived(
message: String,
event: GuildMessageReceivedEvent
) {
}

/**
* On guild command
*
* @param cmd The command/alias
* @param args The args, for example: **!help fun 2** would be **{ "fun", "2" }**
* @param prefix The prefix of the command sent
* @param all The entire raw command **excluding** the prefix
* @param event The [GuildMessageReceivedEvent]
*/
open fun onGuildCommand(
cmd: String,
args: List<String>,
Expand All @@ -108,12 +163,29 @@ abstract class Command(private val bot: BotBase) {
) {
}

/**
* Called when a private message was received
*
* Should not be used for general command handling
*
* @param message The message that the user sent
* @param event The [PrivateMessageReceivedEvent] of the sent message
*/
open fun onPrivateMessageReceived(
message: String,
event: PrivateMessageReceivedEvent
) {
}

/**
* On private command
*
* @param cmd The command/alias
* @param args The args, for example: **!help fun 2** would be **{ "fun", "2" }**
* @param prefix The prefix of the command sent
* @param all The entire raw command **excluding** the prefix
* @param event The [PrivateMessageReceivedEvent]
*/
open fun onPrivateCommand(
cmd: String,
args: List<String>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ fun String.getCommandType(bot: BotBase): CommandType? {
return null
}

abstract class CommandType(val name: String, val displayname: String = StringUtils.capitalize(name.lowercase()))
abstract class CommandType(open val name: String, open val displayname: String = StringUtils.capitalize(name.lowercase()))
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ 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.MessageReceivedEvent
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent
import java.awt.Color

val OTHER_TYPE: CommandType = object : CommandType("OTHER", "Other") {}

/**
* A default (optional) help command.
*
* In order to use it, you **must** register it in [BotBase.commands]!
*
* @property bot the [BotBase] of the bot
* @constructor Creates a help command
*/
@API
class HelpCommand(private val bot: BotBase) : Command(bot) {
open class HelpCommand(private val bot: BotBase) : Command(bot) {
override val command = "help"
override val name = "Help"
override val aliases = setOf<String>()
Expand All @@ -28,6 +37,15 @@ class HelpCommand(private val bot: BotBase) : Command(bot) {
override val type = OTHER_TYPE
override val minArgs = 1

/**
* On help command
*
* @param cmd The command/alias
* @param args The args, for example: **!help fun 2** would be **{ "fun", "2" }**
* @param prefix The prefix of the command sent
* @param all The entire raw command **excluding** the prefix
* @param event The [GuildMessageReceivedEvent]
*/
override fun onGuildCommand(
cmd: String,
args: List<String>,
Expand Down
17 changes: 7 additions & 10 deletions src/main/java/me/dkim19375/dkim19375jdautils/embed/EmbedUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,31 @@ import net.dv8tion.jda.api.entities.MessageEmbed
@API
object EmbedUtils {
@API
fun getEmbedGroups(groups: Map<String, Collection<String>>): Set<MessageEmbed.Field> {
fun getEmbedGroups(groups: Map<String, Collection<String?>?>): Set<MessageEmbed.Field> {
val fields: MutableSet<MessageEmbed.Field> = mutableSetOf()
for (group in groups.entries) {
fields.add(getEmbedGroup(group.key, group.value))
}
return fields
}

private fun combineStrings(first: String, second: String): String {
return "$first$second"
}

@API
fun getEmbedGroup(name: String, values: Collection<String>): MessageEmbed.Field {
if (values.isEmpty()) {
fun getEmbedGroup(name: String, values: Collection<String?>?): MessageEmbed.Field {
if (values.isNullOrEmpty()) {
return MessageEmbed.Field(name, "```\nNone ```", false)
}
var value = "```\n- "
var i = 1
for (string in values) {
string ?: continue
value = if (i == values.size) {
combineStrings(value, string)
"$value$string"
} else {
combineStrings(value, "$string\n- ")
"$value$string\n- "
}
i++
}
value = combineStrings(value, "```")
value = "$value```"
return MessageEmbed.Field(name, value, false)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,55 @@ 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

/**
* An abstract class to listen to detect if a command is valid to send
*
* For example, permission checking is done here
*/
abstract class CustomListener {
/**
* @property antiBot True if the commands should be user-only and not bots
*/
@API
open val antiBot: Boolean = true

/**
* @param event The [MessageReceivedEvent] of this message
* @return true if the command should run, false if not
*/
@API
open fun onMessageReceived(event: MessageReceivedEvent): Boolean = true

/**
* @param event The [GuildMessageReceivedEvent] of this message
* @return true if the command should run, false if not
*/
@API
open fun onGuildMessageReceived(event: GuildMessageReceivedEvent): Boolean = true

/**
* @param event The [PrivateMessageReceivedEvent] of this message
* @return true if the command should run, false if not
*/
@API
open fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent): Boolean = true

/**
* **NOTE:** This will get called on [MessageReceivedEvent], which will also call [PrivateMessageReceivedEvent] *and*
* [GuildMessageReceivedEvent]!!
*
* @param command the [Command] that was sent
* @param cmd the exact [command/alias][String] that was sent
* @param args the [args][List] of the command
* @param member the [Member] who sent the command in [GuildMessageReceivedEvent], or **null** if the command was
* sent in [PrivateMessageReceivedEvent] or [MessageReceivedEvent]
* @param user the [User] who sent the command
* @param guild the [Guild] of where the command was sent
* @param message the [Message] that was sent
* @param channel the [MessageChannel] of where the command was sent
* @param event either [MessageReceivedEvent], [GuildMessageReceivedEvent], or [PrivateMessageReceivedEvent]
* @return true if the command should execute
*/
@API
open fun isValid(
command: Command,
Expand All @@ -38,11 +77,7 @@ abstract class CustomListener {
return false
}
member?.let {
if (channel is GuildChannel) {
if (member.hasPermission(channel, command.permissions)) {
return@let
}
} else if (member.hasPermission(command.permissions)) {
if (command.hasPermissions(user, member, (event as? GuildMessageReceivedEvent)?.channel)) {
return@let
}
if (event !is MessageReceivedEvent) {
Expand All @@ -65,31 +100,4 @@ abstract class CustomListener {
}
return true
}
open fun isValid(
command: Command,
cmd: String,
args: List<String>,
event: GuildMessageReceivedEvent
): Boolean =
isValid(command, cmd, args, event.member, event.author, event.guild, event.message, event.channel, event)

open fun isValid(
command: Command,
cmd: String,
args: List<String>,
event: MessageReceivedEvent
): Boolean = isValid(
command, cmd, args, event.member, event.author, try {
event.guild
} catch (_: IllegalStateException) {
null
}, event.message, event.channel, event
)

open fun isValid(
command: Command,
cmd: String,
args: List<String>,
event: PrivateMessageReceivedEvent
): Boolean = isValid(command, cmd, args, null, event.author, null, event.message, event.channel, event)
}
Loading

0 comments on commit 98cf4d4

Please sign in to comment.