Skip to content

Commit a616e1b

Browse files
committed
feat(command): update sub command system
1 parent 30aec1c commit a616e1b

15 files changed

+91
-122
lines changed

src/main/kotlin/dev/shiron/kotodiscord/controller/CommandController.kt

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,74 +2,91 @@ package dev.shiron.kotodiscord.controller
22

33
import dev.shiron.kotodiscord.util.BotSlashCommandData
44
import dev.shiron.kotodiscord.util.RunnableCommandServiceClass
5-
import dev.shiron.kotodiscord.util.SubCommandsControllerClass
5+
import dev.shiron.kotodiscord.util.SingleCommandServiceClass
6+
import dev.shiron.kotodiscord.util.SubCommandServiceClass
7+
import dev.shiron.kotodiscord.util.meta.SubCommandGroupEnum
68
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent
79
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
810
import net.dv8tion.jda.api.hooks.ListenerAdapter
11+
import net.dv8tion.jda.api.interactions.commands.build.Commands
912
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData
13+
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData
1014
import org.springframework.beans.factory.annotation.Autowired
1115
import org.springframework.context.MessageSource
1216
import org.springframework.stereotype.Controller
1317
import java.util.*
1418

1519
@Controller
1620
class CommandController @Autowired constructor(
17-
runnableCommandServices: List<RunnableCommandServiceClass>,
18-
private val subCommandsControllers: List<SubCommandsControllerClass>,
21+
private val singleCommandServices: List<SingleCommandServiceClass>,
22+
private val subCommandServices: List<SubCommandServiceClass>,
1923
private val messages: MessageSource
2024
) : ListenerAdapter() {
2125

22-
private val commandServices: List<RunnableCommandServiceClass> by lazy {
23-
val commandServices = runnableCommandServices.toMutableList()
24-
for (commandService in runnableCommandServices) {
25-
if (subCommandsControllers.find { it.subcommands.contains(commandService) } !== null) {
26-
commandServices.remove(commandService)
27-
}
26+
override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) {
27+
val command = getCommand(event.name, event.subcommandName)
28+
29+
if (command != null) {
30+
event
31+
.deferReply()
32+
.setEphemeral((event.getOption("shared")?.asBoolean?.not()) ?: command.sharedDefault.not())
33+
.queue()
34+
command.onSlashCommand(
35+
BotSlashCommandData(
36+
event = event
37+
)
38+
)
39+
} else {
40+
event.reply(messages.getMessage("command.error.notfound", arrayOf(event.name), Locale.JAPAN)).queue()
2841
}
29-
commandServices
3042
}
3143

32-
override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) {
33-
if (event.subcommandName !== null) {
44+
override fun onCommandAutoCompleteInteraction(event: CommandAutoCompleteInteractionEvent) {
45+
val command = getCommand(event.name, event.subcommandName)
46+
command?.onAutoComplete(event)
47+
}
48+
49+
fun getCommand(name: String, subcommandName: String?): RunnableCommandServiceClass? {
50+
if (subcommandName !== null) {
3451
// Subcommand
35-
for (subCommandsController in subCommandsControllers) {
36-
if (subCommandsController.meta.name == event.name) {
37-
subCommandsController.onSlashCommand(
38-
BotSlashCommandData(
39-
event = event
40-
)
41-
)
42-
return
52+
for (command in subCommandServices) {
53+
if (command.commandMeta.metadata.commandName == subcommandName && command.commandMeta.group.metadata.commandName == name) {
54+
return command
4355
}
4456
}
4557
} else {
46-
for (command in commandServices) {
47-
if (command.meta.name == event.name) {
48-
event
49-
.deferReply()
50-
.setEphemeral((event.getOption("shared")?.asBoolean?.not()) ?: command.sharedDefault.not())
51-
.queue()
52-
command.onSlashCommand(
53-
BotSlashCommandData(
54-
event = event
55-
)
56-
)
57-
return
58+
// Single command
59+
for (command in singleCommandServices) {
60+
if (command.commandMeta.metadata.commandName == name) {
61+
return command
5862
}
5963
}
6064
}
61-
event.reply(messages.getMessage("command.error.notfound", arrayOf(event.name), Locale.JAPAN)).queue()
65+
return null
6266
}
6367

64-
override fun onCommandAutoCompleteInteraction(event: CommandAutoCompleteInteractionEvent) {
65-
for (command in commandServices) {
66-
if (command.meta.name == event.name) {
67-
command.onAutoComplete(event)
68+
fun getCommandsData(): List<SlashCommandData> {
69+
val subcommands = mutableMapOf<SubCommandGroupEnum, MutableList<SubCommandServiceClass>>()
70+
for (command in subCommandServices) {
71+
if (!subcommands.containsKey(command.commandMeta.group)) {
72+
subcommands[command.commandMeta.group] = mutableListOf()
6873
}
74+
subcommands[command.commandMeta.group]?.add(command)
75+
}
76+
val subCommandsData = subcommands.map {
77+
Commands.slash(
78+
it.key.metadata.commandName,
79+
messages.getMessage(
80+
"command.description.${it.key.metadata.commandName}",
81+
arrayOf(),
82+
Locale.JAPAN
83+
)
84+
).addSubcommands(it.value.map { toSubcommandData(it.slashCommandData) })
6985
}
86+
return singleCommandServices.map { it.slashCommandData } + subCommandsData
7087
}
88+
}
7189

72-
fun getCommandsData(): List<SlashCommandData> {
73-
return commandServices.map { it.slashCommandData } + subCommandsControllers.map { it.slashCommandData }
74-
}
90+
private fun toSubcommandData(slashCommandData: SlashCommandData): SubcommandData {
91+
return SubcommandData(slashCommandData.name, slashCommandData.description)
7592
}

src/main/kotlin/dev/shiron/kotodiscord/controller/VCController.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/main/kotlin/dev/shiron/kotodiscord/service/command/HelloService.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package dev.shiron.kotodiscord.service.command
22

33
import dev.shiron.kotodiscord.util.BotSlashCommandData
4-
import dev.shiron.kotodiscord.util.RunnableCommandServiceClass
5-
import dev.shiron.kotodiscord.util.meta.RunnableCommandEnum
4+
import dev.shiron.kotodiscord.util.SingleCommandServiceClass
5+
import dev.shiron.kotodiscord.util.meta.SingleCommandEnum
66
import org.springframework.beans.factory.annotation.Autowired
77
import org.springframework.context.MessageSource
88
import org.springframework.stereotype.Service
99
import java.util.*
1010

1111
@Service
12-
class HelloService @Autowired constructor(private val messages: MessageSource) : RunnableCommandServiceClass(
13-
RunnableCommandEnum.HELLO.meta,
12+
class HelloService @Autowired constructor(private val messages: MessageSource) : SingleCommandServiceClass(
13+
SingleCommandEnum.HELLO,
1414
messages
1515
) {
1616
override fun onSlashCommand(cmd: BotSlashCommandData) {

src/main/kotlin/dev/shiron/kotodiscord/service/command/HelpService.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package dev.shiron.kotodiscord.service.command
22

33
import dev.shiron.kotodiscord.util.BotSlashCommandData
4-
import dev.shiron.kotodiscord.util.RunnableCommandServiceClass
5-
import dev.shiron.kotodiscord.util.meta.RunnableCommandEnum
4+
import dev.shiron.kotodiscord.util.SingleCommandServiceClass
5+
import dev.shiron.kotodiscord.util.meta.SingleCommandEnum
66
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent
77
import net.dv8tion.jda.api.interactions.commands.OptionType
88
import net.dv8tion.jda.api.interactions.commands.build.OptionData
@@ -14,8 +14,8 @@ import java.util.*
1414
@Service
1515
class HelpService @Autowired constructor(
1616
private val messages: MessageSource
17-
) : RunnableCommandServiceClass(
18-
RunnableCommandEnum.HELP.meta,
17+
) : SingleCommandServiceClass(
18+
SingleCommandEnum.HELP,
1919
messages
2020
) {
2121

@@ -31,7 +31,7 @@ class HelpService @Autowired constructor(
3131
override fun onAutoComplete(event: CommandAutoCompleteInteractionEvent) {
3232
when (event.focusedOption.name) {
3333
"command" -> {
34-
val commands = RunnableCommandEnum.values().map { it.meta.name }
34+
val commands = SingleCommandEnum.values().map { it.metadata.commandName }
3535
event.replyChoiceStrings(
3636
commands.filter {
3737
it.startsWith(event.focusedOption.value.lowercase())
@@ -43,7 +43,7 @@ class HelpService @Autowired constructor(
4343

4444
override fun onSlashCommand(cmd: BotSlashCommandData) {
4545
val command = cmd.event.getOption("command")?.asString?.lowercase()
46-
val commands = RunnableCommandEnum.values().map { it.meta.name }
46+
val commands = SingleCommandEnum.values().map { it.metadata.commandName }
4747
if (command != null) {
4848
if (commands.contains(command)) {
4949
cmd.reply("### $command\n${getHelp(command)}")

src/main/kotlin/dev/shiron/kotodiscord/util/BotServiceClass.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package dev.shiron.kotodiscord.util
33
import dev.shiron.kotodiscord.util.meta.BotServiceMeta
44

55
abstract class BotServiceClass(
6-
val meta: BotServiceMeta
6+
val serviceMeta: BotServiceMeta
77
)

src/main/kotlin/dev/shiron/kotodiscord/util/RunnableCommandServiceClass.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData
99
import org.springframework.context.MessageSource
1010
import java.util.*
1111

12-
abstract class RunnableCommandServiceClass(meta: RunnableCommandMeta, private val messages: MessageSource, val sharedDefault: Boolean = false) : BotServiceClass(meta) {
12+
abstract class RunnableCommandServiceClass(val runMeta: RunnableCommandMeta, private val messages: MessageSource, val sharedDefault: Boolean = false) : BotServiceClass(runMeta) {
1313

1414
open val commandOptions: List<OptionData> = listOf()
1515

@@ -22,7 +22,7 @@ abstract class RunnableCommandServiceClass(meta: RunnableCommandMeta, private va
2222
}
2323

2424
open val slashCommandData: SlashCommandData
25-
get() = Commands.slash(meta.name, messages.getMessage("command.description.${meta.name}", arrayOf(), Locale.JAPAN)).addOptions(commandOptions)
25+
get() = Commands.slash(runMeta.commandName, messages.getMessage("command.description.${runMeta.commandName}", arrayOf(), Locale.JAPAN)).addOptions(commandOptions)
2626
.addOptions(sharedOptionData)
2727

2828
abstract fun onSlashCommand(cmd: BotSlashCommandData)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dev.shiron.kotodiscord.util
2+
3+
import dev.shiron.kotodiscord.util.meta.SingleCommandEnum
4+
import org.springframework.context.MessageSource
5+
6+
abstract class SingleCommandServiceClass(val commandMeta: SingleCommandEnum, messages: MessageSource) : RunnableCommandServiceClass(commandMeta.metadata, messages)

src/main/kotlin/dev/shiron/kotodiscord/util/SubCommandServiceClass.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import org.springframework.context.MessageSource
77
import java.util.*
88

99
abstract class SubCommandServiceClass(
10-
meta: SubCommandEnum,
10+
val commandMeta: SubCommandEnum,
1111
private val messages: MessageSource
12-
) : RunnableCommandServiceClass(meta.meta, messages) {
12+
) : RunnableCommandServiceClass(commandMeta.metadata, messages) {
1313

1414
override val slashCommandData: SlashCommandData
15-
// TODO: group.name
16-
get() = Commands.slash(meta.name, messages.getMessage("command.description.${meta.name}", arrayOf(), Locale.JAPAN)).addOptions(commandOptions)
15+
get() = Commands.slash(commandMeta.metadata.commandName, messages.getMessage("command.description.${commandMeta.group.metadata.commandName}.${commandMeta.metadata.commandName}", arrayOf(), Locale.JAPAN)).addOptions(commandOptions)
1716
.addOptions(sharedOptionData)
1817
}

src/main/kotlin/dev/shiron/kotodiscord/util/SubCommandsControllerClass.kt

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package dev.shiron.kotodiscord.util.meta
22

33
interface BotServiceMeta {
4-
val name: String
4+
val commandName: String
55
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package dev.shiron.kotodiscord.util.meta
22

3-
data class BotSubCommandGroupMeta(override val name: String) : BotServiceMeta
3+
data class BotSubCommandGroupMeta(override val commandName: String) : BotServiceMeta
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package dev.shiron.kotodiscord.util.meta
22

3-
data class RunnableCommandMeta(override val name: String) : BotServiceMeta
3+
data class RunnableCommandMeta(override val commandName: String) : BotServiceMeta
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dev.shiron.kotodiscord.util.meta
22

3-
enum class RunnableCommandEnum(val meta: RunnableCommandMeta) {
3+
enum class SingleCommandEnum(val metadata: RunnableCommandMeta) {
44
HELLO(RunnableCommandMeta("hello")),
55
HELP(RunnableCommandMeta("help"))
66
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package dev.shiron.kotodiscord.util.meta
22

3-
enum class SubCommandGroupEnum(val meta: BotSubCommandGroupMeta) {
3+
enum class SubCommandGroupEnum(val metadata: BotSubCommandGroupMeta) {
44
VC_NOTIFICATION(BotSubCommandGroupMeta("vc_notification"))
55
}
66

7-
enum class SubCommandEnum(val meta: RunnableCommandMeta) {
8-
VC_NOTIFICATION_SET(RunnableCommandMeta("set")),
9-
VC_NOTIFICATION_REMOVE(RunnableCommandMeta("remove")),
10-
VC_NOTIFICATION_LIST(RunnableCommandMeta("list"))
7+
enum class SubCommandEnum(val metadata: RunnableCommandMeta, val group: SubCommandGroupEnum) {
8+
VC_NOTIFICATION_SET(RunnableCommandMeta("set"), SubCommandGroupEnum.VC_NOTIFICATION),
9+
VC_NOTIFICATION_REMOVE(RunnableCommandMeta("remove"), SubCommandGroupEnum.VC_NOTIFICATION),
10+
VC_NOTIFICATION_LIST(RunnableCommandMeta("list"), SubCommandGroupEnum.VC_NOTIFICATION)
1111
}

src/main/resources/messages.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ command.option.command = コマンド名。省略でコマンド一覧を表示
1010
command.description.hello = ことが挨拶を返します
1111
command.description.help = ボットのヘルプを表示します
1212
command.description.vc_notification = ボイスチャンネルの入退室を通知します
13-
command.description.set = ボイスチャンネルの入退室を通知するかどうかを設定します
14-
command.description.list = ボイスチャンネルの入退室を通知するの設定を表示します
15-
command.description.remove = ボイスチャンネルの入退室を通知を解除します
13+
command.description.vc_notification.set = ボイスチャンネルの入退室を通知するかどうかを設定します
14+
command.description.vc_notification.list = ボイスチャンネルの入退室を通知するの設定を表示します
15+
command.description.vc_notification.remove = ボイスチャンネルの入退室を通知を解除します
1616

1717
command.error.notfound = {0}が見つかりませんでした。\n\
1818
内部のエラーかもしれません...ごめんね><

0 commit comments

Comments
 (0)