Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 2 additions & 20 deletions src/main/kotlin/at/hannibal2/skyhanni/discord/CommandListener.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package at.hannibal2.skyhanni.discord

import at.hannibal2.skyhanni.discord.Utils.createHelpEmbed
import at.hannibal2.skyhanni.discord.Utils.logAction
import at.hannibal2.skyhanni.discord.Utils.messageDelete
import at.hannibal2.skyhanni.discord.Utils.reply
import at.hannibal2.skyhanni.discord.Utils.replyWithConsumer
import at.hannibal2.skyhanni.discord.Utils.runDelayed
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.entities.MessageEmbed
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import java.awt.Color
import kotlin.time.Duration.Companion.seconds

class CommandListener(bot: DiscordBot) {
Expand Down Expand Up @@ -76,7 +74,7 @@ class CommandListener(bot: DiscordBot) {
}
}

// allows to use `!<command> -help` instaed of `!help -<command>`
// allows to use `!<command> -help` instead of `!help -<command>`
if (args.size == 2) {
if (args[1] == "-help") {
sendUsageReply(literal)
Expand Down Expand Up @@ -149,22 +147,6 @@ class CommandListener(bot: DiscordBot) {
}

fun existCommand(text: String): Boolean = commands.find { it.name.equals(text, ignoreCase = true) } != null

private fun CommandData.createHelpEmbed(commandName: String): MessageEmbed {
val em = EmbedBuilder()

em.setTitle("Usage: /$commandName <" + this.options.joinToString("> <") { it.name } + ">")
em.setDescription("📋 **${this.description}**")
em.setColor(Color.GREEN)

for (option in this.options) {
em.addField(option.name, option.description, true)
em.addField("Required", if (option.required) "✅" else "❌", true)
em.addBlankField(true)
}

return em.build()
}
}

class Command(
Expand Down
45 changes: 37 additions & 8 deletions src/main/kotlin/at/hannibal2/skyhanni/discord/CommandsData.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
package at.hannibal2.skyhanni.discord

import net.dv8tion.jda.api.interactions.commands.OptionType

object CommandsData {

private val commands = listOf(
CommandData(
name = "help",
description = "Get help for all OR one specific command.",
options = listOf(Option("command", "Command you want to get help for.", required = false)),
options = listOf(
Option(
"command",
"Command you want to get help for.",
required = false,
autoComplete = true
)
),
userCommand = true
),
CommandData(
name = "pr",
description = "Displays useful information about a pull request on GitHub.",
options = listOf(Option("number", "Number of the pull request you want to display."))
options = listOf(
Option(
"number",
"Number of the pull request you want to display.",
type = OptionType.NUMBER
)
),
),
CommandData(
name = "server",
description = "Displays information about a server from our 'useful server list'.",
options = listOf(
Option("keyword", "Keyword of the server you want to display."),
Option("debug", "Display even more useful information (-d to use).", required = false)
Option("keyword", "Keyword of the server you want to display.", autoComplete = true),
Option(
"debug",
"Display even more useful information (-d to use).",
required = false,
type = OptionType.BOOLEAN
)
),
userCommand = true
),
Expand Down Expand Up @@ -79,7 +99,7 @@ object CommandsData {
name = "tagedit",
description = "Edits a tag in the database.",
options = listOf(
Option("tag", "The tag you want to edit."),
Option("tag", "The tag you want to edit.", autoComplete = true),
Option("response", "Response you want the tag to have.")
),
aliases = listOf("tagchange")
Expand All @@ -100,7 +120,7 @@ object CommandsData {
CommandData(
name = "tagdelete",
description = "Deletes a tag from the database.",
options = listOf(Option("keyword", "Keyword of the tag you want to delete.")),
options = listOf(Option("keyword", "Keyword of the tag you want to delete.", autoComplete = true)),
aliases = listOf("tagremove")
),
CommandData(
Expand All @@ -110,11 +130,14 @@ object CommandsData {
)

private val commandMap = commands.associateBy { it.name } +
commands.flatMap { cmd -> cmd.aliases.map { alias -> alias to cmd } }.toMap()
commands.flatMap { cmd -> cmd.aliases.map { alias -> alias to cmd } }

fun getCommand(nameOrAlias: String): CommandData? {
return commandMap[nameOrAlias]
}

fun getCommands(): Map<String, CommandData> =
commandMap.filterKeys { it !in commands.flatMap { cmd -> cmd.aliases } }
}

data class CommandData(
Expand All @@ -125,5 +148,11 @@ data class CommandData(
val userCommand: Boolean = false
)

data class Option(val name: String, val description: String, val required: Boolean = true)
data class Option(
val name: String,
val description: String,
val required: Boolean = true,
val type: OptionType = OptionType.STRING,
val autoComplete: Boolean = false
)

3 changes: 3 additions & 0 deletions src/main/kotlin/at/hannibal2/skyhanni/discord/DiscordBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package at.hannibal2.skyhanni.discord
import at.hannibal2.skyhanni.discord.Utils.messageSend
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import net.dv8tion.jda.api.events.session.ReadyEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import net.dv8tion.jda.api.requests.GatewayIntent
import org.slf4j.LoggerFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class PullRequestCommands(config: BotConfig, commands: CommandListener) {
return
}
val prNumber = args[1].toIntOrNull() ?: run {
reply("unknwon number $PLEADING_FACE (${args[1]})")
reply("unknown number $PLEADING_FACE (${args[1]})")
return
}

Expand Down Expand Up @@ -195,7 +195,7 @@ class PullRequestCommands(config: BotConfig, commands: CommandListener) {
val (_, downloadTime) = timeExecution {
github.downloadArtifact(artifactId, fileRaw)
}
reply("artifact downnloaded in ${downloadTime.format()}")
reply("artifact downloaded in ${downloadTime.format()}")

Utils.unzipFile(fileRaw, fileUnzipped)
fileRaw.delete()
Expand Down Expand Up @@ -230,5 +230,4 @@ class PullRequestCommands(config: BotConfig, commands: CommandListener) {
event.loadPrInfos(pr)
return true
}

}
}
35 changes: 35 additions & 0 deletions src/main/kotlin/at/hannibal2/skyhanni/discord/ServerCommands.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,41 @@ class ServerCommands(private val bot: DiscordBot, commands: CommandListener) {
else server.keyword
}
reply("Server list:\n$list")
private fun MessageReceivedEvent.serverList(args: List<String>) = reply(listServers())
}

fun Server.print(): String = with(this) {
buildString {
append("**$displayName**\n")
if (description.isNotEmpty()) {
append(description)
append("\n")
}
append(inviteLink)
}
}

fun Server.printDebug(): String = with(this) {
buildString {
append("keyword: '$keyword'\n")
append("displayName: '$displayName'\n")
append("description: '$description'\n")
append("inviteLink: '<$inviteLink>'\n")
val aliases = Database.getServerAliases(keyword)
append("aliases: $aliases\n")
append("edit command:\n")
append("`!serveredit $keyword ${displayName.replace(" ", "_")} $inviteLink $description`")
}
}

fun listServers(): String {
val servers = Database.listServers()
if (servers.isEmpty()) return "No servers found."

return "Server list:\n" + servers.joinToString("\n") { server ->
val aliases = Database.getServerAliases(server.keyword)
if (aliases.isNotEmpty()) "${server.keyword} [${aliases.joinToString(", ")}]"
else server.keyword
}

private fun isDiscordInvite(message: String): Boolean = disordServerPattern.matcher(message).find()
Expand Down
126 changes: 126 additions & 0 deletions src/main/kotlin/at/hannibal2/skyhanni/discord/ServerSlashCommands.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package at.hannibal2.skyhanni.discord

import at.hannibal2.skyhanni.discord.Utils.logAction
import at.hannibal2.skyhanni.discord.Utils.replyT
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent

@Suppress("UNUSED_PARAMETER")
class ServerSlashCommands(private val config: BotConfig, commands: SlashCommandListener) {
init {
commands.add(SlashCommand("server", userCommand = true) { event -> event.serverCommand() })
commands.add(SlashCommand("serverlist") { event -> event.serverList() })
commands.add(SlashCommand("serveradd") { event -> event.serverAdd() })
commands.add(SlashCommand("serveredit") { event -> event.serverEdit() })
commands.add(SlashCommand("serveraddalias") { event -> event.serverAddAlias() })
commands.add(SlashCommand("serveraliasdelete") { event -> event.serverAliasDelete() })
commands.add(SlashCommand("serverdelete") { event -> event.serverDelete() })
}

private fun SlashCommandInteractionEvent.serverCommand() {
val keyword = getOption("keyword")?.asString ?: return
val debug = getOption("debug")?.asBoolean ?: false

val server = Database.getServer(keyword)
if (server != null) {
if (debug) {
replyT(server.printDebug())
} else {
replyT(server.print())
}
} else {
replyT("Server with keyword '$keyword' not found.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.serverAdd() {
val keyword = getOption("keyword")?.asString ?: return

if (Database.getServer(keyword) != null) {
replyT("❌ Server already exists. Use `!serveredit` instead.")
return
}

val server = createServer(keyword) ?: return
if (Database.addServer(server)) {
val id = member?.id
replyT("✅ Server '$keyword' added by <@$id>:")
channel.sendMessage(server.print()).queue()
logAction("added server '$keyword'")
} else {
replyT("❌ Failed to add server.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.serverEdit() {
val keyword = getOption("keyword")?.asString ?: return

if (Database.getServer(keyword) == null) {
replyT("❌ Server does not exist. Use `!serveradd` instead.")
return
}

val server = createServer(keyword) ?: return
if (Database.addServer(server)) {
val id = member?.id
replyT("✅ Server '$keyword' edited by <@$id>:")
channel.sendMessage(server.print()).queue()
logAction("edited server '$keyword'")
} else {
replyT("❌ Failed to edit server.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.createServer(keyword: String): Server? {
val displayName = getOption("display_name")?.asString ?: return null
val inviteLink = getOption("invite_link")?.asString ?: return null
val description = getOption("description")?.asString ?: return null

return Server(keyword = keyword, displayName = displayName, inviteLink = inviteLink, description = description)
}

private fun SlashCommandInteractionEvent.serverAddAlias() {
val keyword = getOption("keyword")?.asString ?: return
val alias = getOption("alias")?.asString ?: return

if (Database.getServer(alias) != null) {
replyT("❌ Alias already exists.", ephemeral = true)
return
}
if (Database.getServer(keyword) == null) {
replyT("❌ Server with keyword '$keyword' does not exist.", ephemeral = true)
return
}
if (Database.addServerAlias(keyword, alias)) {
replyT("✅ Alias '$alias' added for server '$keyword'")
logAction("added alias '$alias' for server '$keyword'")
} else {
replyT("❌ Failed to add alias.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.serverAliasDelete() {
val keyword = getOption("keyword")?.asString ?: return
val alias = getOption("alias")?.asString ?: return

if (Database.deleteServerAlias(keyword, alias)) {
replyT("✅ Alias '$alias' deleted from server '$keyword'")
logAction("deleted alias '$alias' for server '$keyword'")

} else {
replyT("❌ Failed to delete alias '$alias' for server '$keyword'.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.serverDelete() {
val keyword = getOption("keyword")?.asString ?: return

if (Database.deleteServer(keyword)) {
replyT("✅ Server '$keyword' deleted!")
logAction("deleted server '$keyword'")
} else {
replyT("❌ Server with keyword '$keyword' not found or deletion failed.", ephemeral = true)
}
}

private fun SlashCommandInteractionEvent.serverList() { replyT(listServers()) }
}
Loading