Add some test commands. Finalize permissions. Add maintainer level.

This commit is contained in:
Julius de Jeu 2019-05-21 23:12:06 +02:00
parent d22c8e57bb
commit bd95ae33dd
13 changed files with 111 additions and 24 deletions

View file

@ -30,11 +30,11 @@ repositories {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.jetbrains.kotlin:kotlin-reflect'
testCompile group: 'junit', name: 'junit', version: '4.12'
testImplementation "org.junit.jupiter:junit-jupiter:5.4.2"
implementation 'net.dv8tion:JDA:4.ALPHA.0_88' implementation 'net.dv8tion:JDA:4.ALPHA.0_88'
// runtimeOnly "ch.qos.logback:logback-classic:1.2.1"
implementation "com.h2database:h2" implementation "com.h2database:h2"
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

View file

@ -1,9 +1,6 @@
package nl.voidcorp.discord package nl.voidcorp.discord
import net.dv8tion.jda.api.JDABuilder import net.dv8tion.jda.api.JDABuilder
import nl.voidcorp.discord.command.Command
import nl.voidcorp.discord.command.CommandMessage
import nl.voidcorp.discord.command.CommandResult
import nl.voidcorp.discord.events.CommandListener import nl.voidcorp.discord.events.CommandListener
import nl.voidcorp.discord.events.OttoListener import nl.voidcorp.discord.events.OttoListener
import org.springframework.stereotype.Component import org.springframework.stereotype.Component

View file

@ -2,7 +2,12 @@ package nl.voidcorp.discord.command
import net.dv8tion.jda.api.Permission import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.entities.ChannelType import net.dv8tion.jda.api.entities.ChannelType
import net.dv8tion.jda.api.entities.Member
import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import nl.voidcorp.discord.creator
import nl.voidcorp.discord.storage.GuildRepo
import nl.voidcorp.discord.storage.GuildStore
import org.springframework.beans.factory.annotation.Autowired
import java.util.* import java.util.*
@ -10,11 +15,12 @@ abstract class Command(
val name: String, val name: String,
val helpMesage: String = "", val helpMesage: String = "",
val usage: String = "", val usage: String = "",
val commandGroup: CommandLevel = CommandGroup.VERIFIED, val commandLevel: CommandLevel = CommandGroup.VERIFIED,
val aliases: List<String> = emptyList(), val aliases: List<String> = emptyList(),
val location: CommandSource = CommandSource.BOTH, val location: CommandSource = CommandSource.BOTH
val permissions: Set<Permission> = emptySet()
) { ) {
@Autowired
lateinit var repo: GuildRepo
fun onCommand(event: MessageReceivedEvent, prefix: String): CommandResult { fun onCommand(event: MessageReceivedEvent, prefix: String): CommandResult {
val starts = val starts =
@ -34,7 +40,7 @@ abstract class Command(
event.message.contentRaw.drop(prefix.length).trim() event.message.contentRaw.drop(prefix.length).trim()
) else CommandResult.NOPE ) else CommandResult.NOPE
CommandSource.BOTH -> CommandSource.BOTH ->
if (event.channelType == ChannelType.PRIVATE) guildStuff( if (event.channelType == ChannelType.TEXT) guildStuff(
event, event,
event.message.contentRaw.drop(prefix.length).trim() event.message.contentRaw.drop(prefix.length).trim()
) )
@ -43,7 +49,7 @@ abstract class Command(
} }
private fun guildStuff(event: MessageReceivedEvent, str: String) = private fun guildStuff(event: MessageReceivedEvent, str: String) =
if ((permissions.intersect(event.member?.permissions as Iterable<Permission>).isNotEmpty() or permissions.isEmpty())) try { if (isPermOK(commandLevel, getLevel(event.member!!))) try {
handle(CommandMessage(event, translateCommandline(str))) handle(CommandMessage(event, translateCommandline(str)))
} catch (e: Exception) { } catch (e: Exception) {
CommandResult.ERROR CommandResult.ERROR
@ -57,11 +63,36 @@ abstract class Command(
abstract fun handle(event: CommandMessage): CommandResult abstract fun handle(event: CommandMessage): CommandResult
fun getLevel(member: Member): CommandLevel {
val guildStore = repo.findByGuildId(member.guild.idLong) ?: GuildStore(-1)
return when {
member.user.idLong == creator.idLong -> CommandGroup.MAINTAINER
member.hasPermission(Permission.ADMINISTRATOR)
or guildStore.adminRoles.intersect(member.roles.map { it.idLong }).isNotEmpty()
-> CommandGroup.ADMIN
guildStore.moderatorRoles.intersect(member.roles.map { it.idLong }).isNotEmpty()
-> CommandGroup.MODERATOR
member.roles.isNotEmpty() or guildStore.defaultVerified -> CommandGroup.VERIFIED
else -> CommandGroup.UNVERIFIED
}
}
companion object { companion object {
var settings = CommandSettings() var settings = CommandSettings()
fun isPermOK(required: CommandLevel, user: CommandLevel): Boolean {
var test: CommandLevel? = required
while (test != null) {
if (test == user) {
return true
}
test = test.parent
}
return false
}
/** /**
* [code borrowed from ant.jar] * [code borrowed from ant.jar]
* Crack a command line. * Crack a command line.

View file

@ -1,7 +1,8 @@
package nl.voidcorp.discord.command package nl.voidcorp.discord.command
object CommandGroup { object CommandGroup {
val ADMIN = CommandLevel("Administrator") val MAINTAINER = CommandLevel("Maintainer")
val ADMIN = CommandLevel("Administrator", MAINTAINER)
val MODERATOR = CommandLevel("Moderator", ADMIN) val MODERATOR = CommandLevel("Moderator", ADMIN)
val VERIFIED = CommandLevel("Verified", MODERATOR) val VERIFIED = CommandLevel("Verified", MODERATOR)
val UNVERIFIED = CommandLevel("Unverified", VERIFIED) val UNVERIFIED = CommandLevel("Unverified", VERIFIED)

View file

@ -1,3 +1,3 @@
package nl.voidcorp.discord.command package nl.voidcorp.discord.command
data class CommandLevel(val levelNAme: String, val parent: CommandLevel? = null) data class CommandLevel(val levelName: String, val parent: CommandLevel? = null)

View file

@ -0,0 +1,19 @@
package nl.voidcorp.discord.commands
import nl.voidcorp.discord.command.Command
import nl.voidcorp.discord.command.CommandGroup
import nl.voidcorp.discord.command.CommandMessage
import nl.voidcorp.discord.command.CommandResult
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service
@Service
class DebugCommand(@Lazy private val list: List<Command>) : Command("debug", commandLevel = CommandGroup.MAINTAINER) {
override fun handle(event: CommandMessage): CommandResult {
event.reply("DebugInfo")
event.reply("Commands found: ${list.size}")
event.reply(list.joinToString(prefix = "`debug`, ") { "`${it.name}`" })
event.reply("EndDebugInfo")
return CommandResult.SUCCESS
}
}

View file

@ -0,0 +1,14 @@
package nl.voidcorp.discord.commands
import nl.voidcorp.discord.command.Command
import nl.voidcorp.discord.command.CommandMessage
import nl.voidcorp.discord.command.CommandResult
import org.springframework.stereotype.Component
@Component
class PermissionLevelCommand : Command("permissions") {
override fun handle(event: CommandMessage): CommandResult {
event.reply("Your highest permission level is `${getLevel(event.member!!).levelName}`")
return CommandResult.SUCCESS
}
}

View file

@ -57,13 +57,13 @@ class CommandListener(
CommandResult.SUCCESS -> Unit CommandResult.SUCCESS -> Unit
CommandResult.ERROR -> CommandMessage( CommandResult.ERROR -> CommandMessage(
event, event,
listOf() emptyList()
).reply(MessageBuilder("There was an error executing this command").build()) ).reply(MessageBuilder("There was an error executing this command").build())
CommandResult.PERMISSIONS -> CommandMessage(event, listOf()).reply( CommandResult.PERMISSIONS -> CommandMessage(event, emptyList()).reply(
MessageBuilder("Sorry, but you don't seem to have the needed permissions to execute this command...").build() MessageBuilder("Sorry, but you don't seem to have the needed permissions to execute this command...").build()
) )
CommandResult.NOPE -> logger.warn("The command ${command.name} somehow responded with a nope?") CommandResult.NOPE -> logger.warn("The command ${command.name} somehow responded with a nope?")
CommandResult.PARAMETERS -> CommandMessage(event, listOf()).reply( CommandResult.PARAMETERS -> CommandMessage(event, emptyList()).reply(
MessageBuilder("Sorry, but you are missing some parameters: `${command.usage}`").build() MessageBuilder("Sorry, but you are missing some parameters: `${command.usage}`").build()
) )
} }

View file

@ -0,0 +1,9 @@
package nl.voidcorp.discord.storage
import org.springframework.data.jpa.repository.JpaRepository
interface GuildRepo : JpaRepository<GuildStore, Long> {
fun findByGuildId(id: Long): GuildStore?
fun existsByGuildId(id: Long): Boolean
}

View file

@ -1,12 +1,18 @@
package nl.voidcorp.discord.storage package nl.voidcorp.discord.storage
import javax.annotation.Generated import javax.annotation.Generated
import javax.persistence.ElementCollection
import javax.persistence.Entity import javax.persistence.Entity
import javax.persistence.Id import javax.persistence.Id
@Entity @Entity
data class GuildStore( data class GuildStore(
var guildId: Long,
@ElementCollection var moderatorRoles: MutableList<Long> = mutableListOf(),
@ElementCollection var adminRoles: MutableList<Long> = mutableListOf(),
var defaultVerified: Boolean = false,
@Id @Id
@Generated @Generated
var id: Long? = null) var id: Long? = null
)

View file

@ -1,8 +0,0 @@
package nl.voidcorp.discord.storage
import org.springframework.data.repository.Repository
interface GuildRepo : Repository<GuildStore, Long> {
fun findById(id: Long): GuildStore
}

View file

@ -0,0 +1,14 @@
package nl.voidcorp.discord
import nl.voidcorp.discord.command.Command
import nl.voidcorp.discord.command.CommandGroup
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class CommandTest {
@Test
fun `Test permission slide Verified into Admin`() {
Assertions.assertTrue(Command.isPermOK(CommandGroup.VERIFIED, CommandGroup.ADMIN))
}
}

View file

@ -0,0 +1,4 @@
package nl.voidcorp.discord
class MainTest {
}