Skip to content
This repository has been archived by the owner on Apr 16, 2023. It is now read-only.

Commit

Permalink
Rewrite prefixes to be more composable
Browse files Browse the repository at this point in the history
  • Loading branch information
BartArys committed May 30, 2020
1 parent 7016511 commit 68fbb7a
Show file tree
Hide file tree
Showing 23 changed files with 566 additions and 74 deletions.
Empty file removed CHANGELOG
Empty file.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
#0.1.1
# 0.2.0

## Changes

* Prefixes have been reworked considerably. #3

# 0.1.1

## Fixes

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ suspend fun main() = bot("token") {
}

val prefix = prefix {
kord { "!" }
kord { literal("!") or mention() }
}

fun testModule() = module("test-module") {
Expand Down
3 changes: 2 additions & 1 deletion kordx-commands-processor/src/test/kotlin/ProcessFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.gitlab.kordlib.kordx.commands.kord.module.command
import com.gitlab.kordlib.kordx.commands.kord.module.commands
import com.gitlab.kordlib.kordx.commands.kord.module.module
import com.gitlab.kordlib.kordx.commands.model.context.CommonContext
import com.gitlab.kordlib.kordx.commands.model.prefix.literal
import com.gitlab.kordlib.kordx.commands.model.prefix.prefix
import com.gitlab.kordlib.kordx.commands.model.processor.BaseEventHandler
import com.gitlab.kordlib.kordx.commands.model.processor.EventSource
Expand Down Expand Up @@ -47,7 +48,7 @@ val propertyCommand
get() = command("swing") {}

val kordPrefix = prefix {
kord { "+" }
kord { literal("+") }
}

suspend fun testReference() = bot("sample") {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.gitlab.kordlib.kordx.commands.kord.model.prefix

import com.gitlab.kordlib.core.behavior.GuildBehavior
import com.gitlab.kordlib.core.behavior.MemberBehavior
import com.gitlab.kordlib.core.behavior.UserBehavior
import com.gitlab.kordlib.core.behavior.channel.MessageChannelBehavior
import com.gitlab.kordlib.core.entity.channel.Channel
import com.gitlab.kordlib.core.event.message.MessageCreateEvent
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixBuilder
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixRule

/**
* Creates a [PrefixRule] that supplies][supplier] a prefix based on the [event's][MessageCreateEvent] guild.
*
* Events created outside of guilds (DMs) will automatically be denied. Invocations of the [supplier] that return
* `null` will be considered as denied as well.
*/
fun PrefixBuilder.guild(
supplier: (guild: GuildBehavior) -> String?
): PrefixRule<MessageCreateEvent> = PrefixRule { message, context ->
val guild = context.message.guild ?: return@PrefixRule PrefixRule.Result.Denied
val prefix = supplier(guild) ?: return@PrefixRule PrefixRule.Result.Denied
if (message.startsWith(prefix)) PrefixRule.Result.Accepted(prefix)
else PrefixRule.Result.Denied
}

/**
* Creates a [PrefixRule] that supplies][supplier] a prefix based on the [event's][MessageCreateEvent] channel.
*
* Invocations of the [supplier] that return `null` will be considered as [denied][PrefixRule.Result.Denied].
*/
fun PrefixBuilder.channel(
supplier: (channel: MessageChannelBehavior) -> String?
): PrefixRule<MessageCreateEvent> = PrefixRule { message, context ->
val channel = context.message.channel
val prefix = supplier(channel) ?: return@PrefixRule PrefixRule.Result.Denied
if (message.startsWith(prefix)) PrefixRule.Result.Accepted(prefix)
else PrefixRule.Result.Denied
}

/**
* Creates a [PrefixRule] that supplies][supplier] a prefix based on the [event's][MessageCreateEvent] channel.
*
* Events created outside of channels of type [T] will automatically be [denied][PrefixRule.Result.Denied].
* Invocations of the [supplier] that return `null` will be considered as [denied][PrefixRule.Result.Denied] as well.
*/
@JvmName("channelReified")
inline fun <reified T : Channel> PrefixBuilder.channel(
noinline supplier: (channel: T) -> String?
): PrefixRule<MessageCreateEvent> = PrefixRule { message, context ->
val channel = context.message.getChannel()
if (channel !is T) return@PrefixRule PrefixRule.Result.Denied
val prefix = supplier(channel) ?: return@PrefixRule PrefixRule.Result.Denied
if (message.startsWith(prefix)) PrefixRule.Result.Accepted(prefix)
else PrefixRule.Result.Denied
}

/**
* Creates a [PrefixRule] that supplies][supplier] a prefix based on the [event's][MessageCreateEvent] user.
*
* Invocations of the [supplier] that return `null` will be considered as [denied][PrefixRule.Result.Denied].
*/
fun PrefixBuilder.user(
supplier: (user: UserBehavior) -> String?
): PrefixRule<MessageCreateEvent> = PrefixRule { message, context ->
val user = context.message.author ?: return@PrefixRule PrefixRule.Result.Denied
val prefix = supplier(user) ?: return@PrefixRule PrefixRule.Result.Denied
if (message.startsWith(prefix)) PrefixRule.Result.Accepted(prefix)
else PrefixRule.Result.Denied
}

/**
* Creates a [PrefixRule] that supplies][supplier] a prefix based on the [event's][MessageCreateEvent] member.
*
* Invocations of the [supplier] that return `null` will be considered as [denied][PrefixRule.Result.Denied].
*/
fun PrefixBuilder.member(
supplier: (user: MemberBehavior) -> String?
): PrefixRule<MessageCreateEvent> = PrefixRule { message, context ->
val member = context.message.getAuthorAsMember() ?: return@PrefixRule PrefixRule.Result.Denied
val prefix = supplier(member) ?: return@PrefixRule PrefixRule.Result.Denied
if (message.startsWith(prefix)) PrefixRule.Result.Accepted(prefix)
else PrefixRule.Result.Denied
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.gitlab.kordlib.kordx.commands.kord.model.prefix

import com.gitlab.kordlib.core.Kord
import com.gitlab.kordlib.core.event.message.MessageCreateEvent
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixBuilder
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixRule
import org.koin.core.get

/**
* Creates [PrefixRule] that accepts the bot's mention as a valid prefix.
*
* > Note that due to the nature of Discord's mentions requiring a space for them to be rendered in the client,
* this rule will also require and consume a whitespace character directly after the mention.
* If, for example, this rule is enabled and the given input is `"@Bot ping"` the matched prefix will be `"@Bot "`,
* including the space. This also means that simply mentioning the bot `"@Bot"` will not be considered valid.
*/
fun PrefixBuilder.mention(): PrefixRule<MessageCreateEvent> = MentionPrefixRule(get())

internal class MentionPrefixRule(kord: Kord) : PrefixRule<MessageCreateEvent> {

private val regex = Regex("""<@!?${kord.selfId.value}>\s""")

override suspend fun consume(message: String, context: MessageCreateEvent): PrefixRule.Result {
val result = regex.find(message) ?: return PrefixRule.Result.Denied
if (result.range.first != 0) return PrefixRule.Result.Denied
return PrefixRule.Result.Accepted(message.substring(result.range))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ package com.gitlab.kordlib.kordx.commands.kord.model.prefix
import com.gitlab.kordlib.core.event.message.MessageCreateEvent
import com.gitlab.kordlib.kordx.commands.kord.model.processor.KordContext
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixBuilder
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixRule

/**
* Sets the [supplier] as the prefix for the [KordContext].
*/
fun PrefixBuilder.kord(supplier: suspend (MessageCreateEvent) -> String) = add(KordContext, supplier)
inline fun PrefixBuilder.kord(supplier: () -> PrefixRule<MessageCreateEvent>) = add(KordContext, supplier())

/**
* Sets the [supplier] as the prefix for the [KordContext].
*/
fun PrefixBuilder.kord(supplier: PrefixRule<MessageCreateEvent>) = add(KordContext, supplier)
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.gitlab.kordlib.kordx.commands.kord.model.processor

import com.gitlab.kordlib.core.Kord
import com.gitlab.kordlib.core.event.message.MessageCreateEvent
import com.gitlab.kordlib.kordx.commands.kord.model.prefix.mentionPrefix
import com.gitlab.kordlib.kordx.commands.model.context.CommonContext
import com.gitlab.kordlib.kordx.commands.model.prefix.PrefixSupplier
import com.gitlab.kordlib.kordx.commands.model.processor.CommandProcessor
import com.gitlab.kordlib.kordx.commands.model.processor.ProcessorBuilder

private const val PREFIX_FLAG_DEPRECATED_MESSAGE = """
'enableMentionPrefix' is deprecated and has been implemented as a prefix rule instead,
replace it with `or mention()` in the kord prefix configuration.
"""

/**
* ProcessorBuilder with extra utility for the [KordContext].
*
Expand All @@ -18,17 +19,12 @@ class KordProcessorBuilder(val kord: Kord) : ProcessorBuilder() {
/**
* True if `@bot` mentions should work as a substitute for the prefix. Default is `true`.
*/
var enableMentionPrefix: Boolean = true
@Deprecated(PREFIX_FLAG_DEPRECATED_MESSAGE, level = DeprecationLevel.ERROR)
var enableMentionPrefix: Boolean
get() = error(PREFIX_FLAG_DEPRECATED_MESSAGE)
set(value) = error(PREFIX_FLAG_DEPRECATED_MESSAGE)

override suspend fun build(): CommandProcessor {
if (enableMentionPrefix) {
val prefix: PrefixSupplier<MessageCreateEvent>? = (
prefixBuilder[KordContext] ?: prefixBuilder[CommonContext]
)
val newPrefix: PrefixSupplier<MessageCreateEvent> = mentionPrefix(kord.selfId, prefix)
prefixBuilder.add(KordContext, newPrefix)
}

return super.build()
}

Expand Down
Loading

0 comments on commit 68fbb7a

Please sign in to comment.