diff --git a/src/main/kotlin/moe/kageru/kagebot/Globals.kt b/src/main/kotlin/moe/kageru/kagebot/Globals.kt index 86020d1..89eaa19 100644 --- a/src/main/kotlin/moe/kageru/kagebot/Globals.kt +++ b/src/main/kotlin/moe/kageru/kagebot/Globals.kt @@ -3,6 +3,7 @@ package moe.kageru.kagebot import moe.kageru.kagebot.command.Command import moe.kageru.kagebot.config.Config import moe.kageru.kagebot.config.SystemConfig +import moe.kageru.kagebot.features.Features import org.javacord.api.DiscordApi import org.javacord.api.entity.server.Server import java.util.concurrent.atomic.AtomicInteger @@ -13,5 +14,6 @@ object Globals { lateinit var config: Config lateinit var commands: List lateinit var systemConfig: SystemConfig + lateinit var features: Features var commandCounter: AtomicInteger = AtomicInteger(0) } \ No newline at end of file diff --git a/src/main/kotlin/moe/kageru/kagebot/Kagebot.kt b/src/main/kotlin/moe/kageru/kagebot/Kagebot.kt index 24ba345..1fcfbf0 100644 --- a/src/main/kotlin/moe/kageru/kagebot/Kagebot.kt +++ b/src/main/kotlin/moe/kageru/kagebot/Kagebot.kt @@ -4,7 +4,6 @@ import moe.kageru.kagebot.Log.log import moe.kageru.kagebot.Util.checked import moe.kageru.kagebot.config.Config import moe.kageru.kagebot.config.RawConfig -import moe.kageru.kagebot.features.MessageFeature import org.javacord.api.DiscordApiBuilder import org.javacord.api.event.message.MessageCreateEvent import org.javacord.api.event.server.member.ServerMemberJoinEvent @@ -65,18 +64,9 @@ object Kagebot { }) log.info("kagebot Mk II running") Globals.api.addMessageCreateListener { checked { processMessage(it) } } - Globals.config.features.welcome?.let { welcome -> - if (welcome.enabled) { - Globals.api.addServerMemberJoinListener { - checked { welcomeUser(it) } - } - } - } - for (feature in Globals.config.features.allWithMessage()) { - if (feature.commandEnabled) { - Globals.api.addMessageCreateListener { - checked { feature.handle(it) } - } + Globals.config.features.welcome?.let { + Globals.api.addServerMemberJoinListener { + checked { welcomeUser(it) } } } } diff --git a/src/main/kotlin/moe/kageru/kagebot/command/Command.kt b/src/main/kotlin/moe/kageru/kagebot/command/Command.kt index 48a6877..df719f9 100644 --- a/src/main/kotlin/moe/kageru/kagebot/command/Command.kt +++ b/src/main/kotlin/moe/kageru/kagebot/command/Command.kt @@ -6,6 +6,7 @@ import moe.kageru.kagebot.Log.log import moe.kageru.kagebot.MessageUtil import moe.kageru.kagebot.Util.doIf import moe.kageru.kagebot.config.RawCommand +import moe.kageru.kagebot.features.MessageFeature import org.javacord.api.entity.message.MessageAuthor import org.javacord.api.entity.message.embed.EmbedBuilder import org.javacord.api.event.message.MessageCreateEvent @@ -20,6 +21,7 @@ class Command(cmd: RawCommand) { private val actions: MessageActions? val regex: Regex? val embed: EmbedBuilder? + val feature: MessageFeature? init { trigger = cmd.trigger ?: throw IllegalArgumentException("Every command must have a trigger.") @@ -32,6 +34,7 @@ class Command(cmd: RawCommand) { actions = cmd.actions?.let { MessageActions(it) } regex = if (matchType == MatchType.REGEX) Regex(trigger) else null embed = cmd.embed?.let(MessageUtil::mapToEmbed) + feature = cmd.feature?.let { Globals.features.findByString(it) } } fun isAllowed(message: MessageCreateEvent) = permissions?.isAllowed(message) ?: true @@ -53,6 +56,7 @@ class Command(cmd: RawCommand) { this.embed?.let { message.channel.sendMessage(embed) } + this.feature?.handle(message) } fun matches(msg: String) = this.matchType.matches(msg, this) diff --git a/src/main/kotlin/moe/kageru/kagebot/config/Config.kt b/src/main/kotlin/moe/kageru/kagebot/config/Config.kt index 6a03468..8dc41d7 100644 --- a/src/main/kotlin/moe/kageru/kagebot/config/Config.kt +++ b/src/main/kotlin/moe/kageru/kagebot/config/Config.kt @@ -16,9 +16,11 @@ class Config(rawConfig: RawConfig) { init { Globals.systemConfig = system Globals.server = api.getServerById(system.serverId).orElseThrow() + Globals.features = rawConfig.features?.let(::Features) ?: Features(RawFeatures(null)) + // TODO: remove this + this.features = Globals.features Globals.commands = rawConfig.commands?.map(::Command) ?: emptyList() Globals.config = this - this.features = rawConfig.features?.let(::Features) ?: Features.NONE } fun reloadLocalization(rawLocalization: RawLocalization) { diff --git a/src/main/kotlin/moe/kageru/kagebot/config/RawCommands.kt b/src/main/kotlin/moe/kageru/kagebot/config/RawCommands.kt index 4cfeb2f..1680682 100644 --- a/src/main/kotlin/moe/kageru/kagebot/config/RawCommands.kt +++ b/src/main/kotlin/moe/kageru/kagebot/config/RawCommands.kt @@ -8,9 +8,10 @@ class RawCommand( val matchType: String?, val permissions: RawPermissions?, @SerializedName("action") val actions: RawMessageActions?, - val embed: Map? + val embed: Map?, + val feature: String? ) class RawPermissions(val hasOneOf: List?, val hasNoneOf: List?, val onlyDM: Boolean) class RawMessageActions(val delete: Boolean, val redirect: RawRedirect?) -class RawRedirect(val target: String?, val anonymous: Boolean) +class RawRedirect(val target: String?, val anonymous: Boolean) \ No newline at end of file diff --git a/src/main/kotlin/moe/kageru/kagebot/config/RawFeatures.kt b/src/main/kotlin/moe/kageru/kagebot/config/RawFeatures.kt index 22d6bad..563be58 100644 --- a/src/main/kotlin/moe/kageru/kagebot/config/RawFeatures.kt +++ b/src/main/kotlin/moe/kageru/kagebot/config/RawFeatures.kt @@ -1,16 +1,4 @@ package moe.kageru.kagebot.config -import com.google.gson.annotations.SerializedName - - -class RawFeatures(val welcome: RawWelcomeFeature?, val debug: RawDebugFeature?, val help: RawHelpFeature?) -class RawWelcomeFeature( - val enable: Boolean, - val content: Map?, - val fallbackChannel: String?, - val fallbackMessage: String?, - @SerializedName("command") val commandEnabled: Boolean -) - -class RawDebugFeature(val enable: Boolean) -class RawHelpFeature(val enable: Boolean) +class RawFeatures(val welcome: RawWelcomeFeature?) +class RawWelcomeFeature(val content: Map?, val fallbackChannel: String?, val fallbackMessage: String?) diff --git a/src/main/kotlin/moe/kageru/kagebot/features/DebugFeature.kt b/src/main/kotlin/moe/kageru/kagebot/features/DebugFeature.kt index 66e6d56..2a0f8ac 100644 --- a/src/main/kotlin/moe/kageru/kagebot/features/DebugFeature.kt +++ b/src/main/kotlin/moe/kageru/kagebot/features/DebugFeature.kt @@ -3,21 +3,17 @@ package moe.kageru.kagebot.features import com.sun.management.OperatingSystemMXBean import moe.kageru.kagebot.Globals import moe.kageru.kagebot.MessageUtil -import moe.kageru.kagebot.config.RawDebugFeature import org.javacord.api.entity.message.embed.EmbedBuilder import org.javacord.api.event.message.MessageCreateEvent import java.lang.management.ManagementFactory import java.time.Duration import java.time.temporal.ChronoUnit -class DebugFeature(rawDebugFeatures: RawDebugFeature): MessageFeature() { - override val commandEnabled = rawDebugFeatures.enable +class DebugFeature : MessageFeature() { override fun handleInternal(message: MessageCreateEvent) { if (message.messageAuthor.isBotOwner) { - if (message.readableMessageContent.startsWith("!debugstats")) { - message.channel.sendMessage(getPerformanceStats()) - } + message.channel.sendMessage(getPerformanceStats()) } } diff --git a/src/main/kotlin/moe/kageru/kagebot/features/Features.kt b/src/main/kotlin/moe/kageru/kagebot/features/Features.kt index 1bddcda..8949ff0 100644 --- a/src/main/kotlin/moe/kageru/kagebot/features/Features.kt +++ b/src/main/kotlin/moe/kageru/kagebot/features/Features.kt @@ -2,19 +2,14 @@ package moe.kageru.kagebot.features import moe.kageru.kagebot.config.RawFeatures -class Features(val welcome: WelcomeFeature?, val debug: DebugFeature?, val help: HelpFeature?) { +class Features(val welcome: WelcomeFeature?, debug: DebugFeature, help: HelpFeature) { constructor(rawFeatures: RawFeatures) : this( rawFeatures.welcome?.let(::WelcomeFeature), - rawFeatures.debug?.let(::DebugFeature), - rawFeatures.help?.let(::HelpFeature) + DebugFeature(), + HelpFeature() ) - fun all() = listOfNotNull(this.welcome, this.debug, this.help) - fun allWithMessage() = all().filterIsInstance() + private val featureMap = mapOf("help" to help, "debug" to debug, "welcome" to welcome) - companion object { - val NONE = Features(null, null, null) - } -} - -interface Feature \ No newline at end of file + fun findByString(feature: String) = featureMap[feature] +} \ No newline at end of file diff --git a/src/main/kotlin/moe/kageru/kagebot/features/HelpFeature.kt b/src/main/kotlin/moe/kageru/kagebot/features/HelpFeature.kt index 6d69b8c..268771c 100644 --- a/src/main/kotlin/moe/kageru/kagebot/features/HelpFeature.kt +++ b/src/main/kotlin/moe/kageru/kagebot/features/HelpFeature.kt @@ -3,24 +3,18 @@ package moe.kageru.kagebot.features import moe.kageru.kagebot.Globals import moe.kageru.kagebot.MessageUtil import moe.kageru.kagebot.command.MatchType -import moe.kageru.kagebot.config.RawHelpFeature import org.javacord.api.event.message.MessageCreateEvent -class HelpFeature(rawFeature: RawHelpFeature) : MessageFeature() { - override val commandEnabled = rawFeature.enable - +class HelpFeature : MessageFeature() { override fun handleInternal(message: MessageCreateEvent) { - if (message.readableMessageContent.startsWith("!help")) { - message.channel.sendMessage( - MessageUtil.getEmbedBuilder() - .addField("Commands:", listCommands(message)) - ) - } + message.channel.sendMessage( + MessageUtil.getEmbedBuilder() + .addField("Commands:", listCommands(message)) + ) } +} - private fun listCommands(message: MessageCreateEvent) = - Globals.commands - .filter { it.matchType == MatchType.PREFIX && it.isAllowed(message) } - .map { it.trigger } - .joinToString("\n") -} \ No newline at end of file +private fun listCommands(message: MessageCreateEvent) = Globals.commands + .filter { it.matchType == MatchType.PREFIX && it.isAllowed(message) } + .map { it.trigger } + .joinToString("\n") \ No newline at end of file diff --git a/src/main/kotlin/moe/kageru/kagebot/features/MessageFeature.kt b/src/main/kotlin/moe/kageru/kagebot/features/MessageFeature.kt index d0def66..83914f5 100644 --- a/src/main/kotlin/moe/kageru/kagebot/features/MessageFeature.kt +++ b/src/main/kotlin/moe/kageru/kagebot/features/MessageFeature.kt @@ -1,16 +1,10 @@ package moe.kageru.kagebot.features -import moe.kageru.kagebot.Globals import org.javacord.api.event.message.MessageCreateEvent -abstract class MessageFeature : Feature { - abstract val commandEnabled: Boolean - +abstract class MessageFeature { fun handle(message: MessageCreateEvent) { - if (commandEnabled) { - Globals.commandCounter.incrementAndGet() - handleInternal(message) - } + handleInternal(message) } internal abstract fun handleInternal(message: MessageCreateEvent) diff --git a/src/main/kotlin/moe/kageru/kagebot/features/WelcomeFeature.kt b/src/main/kotlin/moe/kageru/kagebot/features/WelcomeFeature.kt index 2501a0f..dd7c5b8 100644 --- a/src/main/kotlin/moe/kageru/kagebot/features/WelcomeFeature.kt +++ b/src/main/kotlin/moe/kageru/kagebot/features/WelcomeFeature.kt @@ -8,15 +8,10 @@ import org.javacord.api.entity.message.embed.EmbedBuilder import org.javacord.api.event.message.MessageCreateEvent class WelcomeFeature(rawWelcome: RawWelcomeFeature) : MessageFeature() { - override val commandEnabled = rawWelcome.commandEnabled - override fun handleInternal(message: MessageCreateEvent) { - if (message.readableMessageContent == "!welcome") { - message.channel.sendMessage(embed) - } + message.channel.sendMessage(embed) } - val enabled: Boolean = rawWelcome.enable val embed: EmbedBuilder? by lazy { rawWelcome.content?.let(MessageUtil::mapToEmbed) } diff --git a/src/main/resources/config.toml b/src/main/resources/config.toml index dd9e70a..3d2d6ea 100644 --- a/src/main/resources/config.toml +++ b/src/main/resources/config.toml @@ -13,9 +13,6 @@ messageDeleted = "Your message was deleted because it contained a banned word or # If the user has disabled their DMs, the fallbackMessage will be sent in the fallbackChannel instead. # If no fallback channel or message is specified, no fallback will be sent. [feature.welcome] -enable = true -# enable the !welcome command which will print the welcome embed -command = true fallbackChannel = "555097559023222825" fallbackMessage = "@@ I would like to greet you, but I can’t. :(" # This is a list of pairs where the key is the title and the value the content of the paragraph. @@ -24,13 +21,6 @@ fallbackMessage = "@@ I would like to greet you, but I can’t. :(" "Welcome to the Server" = "This is the content of the first paragraph" "Second paragraph heading" = "Second paragraph content" -# allow the bot owner to get debug stats -[feature.debug] -enable = true - -[feature.help] -enable = true - [[command]] trigger = "!ping" response = "pong" @@ -95,3 +85,15 @@ response = "redirected" [command.action.redirect] target = "555097559023222825" anonymous = true + +[[command]] +trigger = "!debug" +feature = "debug" + +[[command]] +trigger = "!welcome" +feature = "welcome" + +[[command]] +trigger = "!help" +feature = "help" diff --git a/src/test/kotlin/moe/kageru/kagebot/ConfigTest.kt b/src/test/kotlin/moe/kageru/kagebot/ConfigTest.kt index 4004aee..a24c06d 100644 --- a/src/test/kotlin/moe/kageru/kagebot/ConfigTest.kt +++ b/src/test/kotlin/moe/kageru/kagebot/ConfigTest.kt @@ -9,6 +9,6 @@ class ConfigTest : StringSpec({ "should properly parse test config" { Globals.config shouldNotBe null Globals.systemConfig shouldNotBe null - Globals.commands shouldBe emptyList() + Globals.commands.size shouldBe 2 } }) \ No newline at end of file diff --git a/src/test/kotlin/moe/kageru/kagebot/features/DebugFeatureTest.kt b/src/test/kotlin/moe/kageru/kagebot/features/DebugFeatureTest.kt index 0a801d1..4e33c83 100644 --- a/src/test/kotlin/moe/kageru/kagebot/features/DebugFeatureTest.kt +++ b/src/test/kotlin/moe/kageru/kagebot/features/DebugFeatureTest.kt @@ -4,8 +4,8 @@ import io.kotlintest.specs.StringSpec import io.mockk.every import io.mockk.mockk import io.mockk.verify +import moe.kageru.kagebot.Kagebot import moe.kageru.kagebot.TestUtil -import moe.kageru.kagebot.config.RawDebugFeature import org.javacord.api.entity.message.embed.EmbedBuilder import org.javacord.api.event.message.MessageCreateEvent @@ -14,19 +14,19 @@ class DebugFeatureTest : StringSpec({ // this will fail if the bot tries to execute more than it should // because the mock does not provide the necessary methods "should ignore regular users" { - val message = mockk { - every { messageAuthor.isBotOwner } returns false - } - DebugFeature(RawDebugFeature(true)).handle(message) + val message = TestUtil.mockMessage("!debug") + every { message.messageAuthor.isBotOwner } returns false + Kagebot.processMessage(message) + DebugFeature().handle(message) verify(exactly = 0) { message.channel.sendMessage(any()) } } "should return something" { val message = mockk { every { messageAuthor.isBotOwner } returns true - every { readableMessageContent } returns "!debugstats something" + every { readableMessageContent } returns "!debug" every { channel.sendMessage(any()) } returns mockk() } - DebugFeature(RawDebugFeature(true)).handle(message) + DebugFeature().handle(message) verify(exactly = 1) { message.channel.sendMessage(any()) } } }) \ No newline at end of file diff --git a/src/test/kotlin/moe/kageru/kagebot/features/HelpFeatureTest.kt b/src/test/kotlin/moe/kageru/kagebot/features/HelpFeatureTest.kt index 6bd54c6..5a641aa 100644 --- a/src/test/kotlin/moe/kageru/kagebot/features/HelpFeatureTest.kt +++ b/src/test/kotlin/moe/kageru/kagebot/features/HelpFeatureTest.kt @@ -4,18 +4,21 @@ import io.kotlintest.specs.StringSpec import io.mockk.every import io.mockk.mockk import moe.kageru.kagebot.Globals +import moe.kageru.kagebot.Kagebot import moe.kageru.kagebot.TestUtil -import moe.kageru.kagebot.TestUtil.withReplyContents import moe.kageru.kagebot.TestUtil.mockMessage import moe.kageru.kagebot.TestUtil.withCommands -import moe.kageru.kagebot.config.RawHelpFeature +import moe.kageru.kagebot.TestUtil.withReplyContents import org.javacord.api.entity.message.embed.EmbedBuilder -import java.util.Optional +import java.util.* class HelpFeatureTest : StringSpec({ val sentEmbeds = mutableListOf() TestUtil.prepareTestEnvironment(sentEmbeds = sentEmbeds) val commandConfig = """ + [[command]] + trigger = "!help" + feature = "help" [[command]] trigger = "!ping" [[command]] @@ -33,9 +36,7 @@ class HelpFeatureTest : StringSpec({ val expected = listOf("!ping", "!something") val unexpected = listOf("not a prefix", "!prison") withReplyContents(expected = expected, unexpected = unexpected) { replies -> - HelpFeature(RawHelpFeature(true)) - .handle(message = mockMessage("!help", replyEmbeds = replies)) - //Kagebot.processMessage(TestUtil.mockMessage("!help", replyEmbeds = replies)) + Kagebot.processMessage(mockMessage("!help", replyEmbeds = replies)) } } } @@ -50,11 +51,8 @@ class HelpFeatureTest : StringSpec({ Globals.server.getRolesByNameIgnoreCase("testrole")[0] ) }) - HelpFeature(RawHelpFeature(true)) - .handle(message = message) - //Kagebot.processMessage(TestUtil.mockMessage("!help", replyEmbeds = replies)) + Kagebot.processMessage(message) } } } }) - diff --git a/src/test/resources/testconfig.toml b/src/test/resources/testconfig.toml index 4c42ac4..3a9638b 100644 --- a/src/test/resources/testconfig.toml +++ b/src/test/resources/testconfig.toml @@ -8,7 +8,6 @@ redirectedMessage = "says" messageDeleted = "message dongered" [feature.welcome] -enable = true fallbackChannel = "123" fallbackMessage = "@@ welcome" # This is a list of pairs where the key is the title and the value the content of the paragraph. @@ -17,5 +16,10 @@ fallbackMessage = "@@ welcome" "Welcome to the Server" = "This is the content of the first paragraph" "Second paragraph heading" = "Second paragraph content" -[feature.help] -enable = true \ No newline at end of file +[[command]] +trigger = "!debug" +feature = "debug" + +[[command]] +trigger = "!welcome" +feature = "welcome" \ No newline at end of file