Skip to content

Commit

Permalink
update linkie, close #6
Browse files Browse the repository at this point in the history
Signed-off-by: shedaniel <daniel@shedaniel.me>
  • Loading branch information
shedaniel committed Jan 24, 2021
1 parent 306735a commit fa07887
Show file tree
Hide file tree
Showing 33 changed files with 110 additions and 102 deletions.
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ repositories {
}

dependencies {
compile("me.shedaniel:linkie-core:1.0.45")
compile("com.discord4j:discord4j-core:3.1.3-SNAPSHOT") {
compile("me.shedaniel:linkie-core:1.0.55")
compile("com.discord4j:discord4j-core:3.1.3") {
force = true
}
compile "org.graalvm.js:js-scriptengine:20.2.0"
Expand Down Expand Up @@ -68,6 +68,7 @@ compileKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions {
freeCompilerArgs = ["-Xopt-in=kotlin.RequiresOptIn", "-Xinline-classes"]
languageVersion = "1.4"
}
}

Expand Down
36 changes: 22 additions & 14 deletions src/main/kotlin/me/shedaniel/linkie/discord/CommandBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package me.shedaniel.linkie.discord

import com.soywiz.korio.async.runBlockingNoJs
import discord4j.common.util.Snowflake
import discord4j.core.`object`.entity.Member
import discord4j.core.`object`.entity.Message
Expand All @@ -28,33 +29,40 @@ import me.shedaniel.linkie.InvalidUsageException
import me.shedaniel.linkie.MappingsProvider
import me.shedaniel.linkie.Namespace
import me.shedaniel.linkie.discord.config.ConfigManager
import me.shedaniel.linkie.discord.utils.*
import me.shedaniel.linkie.discord.utils.addInlineField
import me.shedaniel.linkie.discord.utils.buildReactions
import me.shedaniel.linkie.discord.utils.content
import me.shedaniel.linkie.discord.utils.sendEdit
import me.shedaniel.linkie.discord.utils.sendEditEmbed
import me.shedaniel.linkie.discord.utils.sendEmbedMessage
import me.shedaniel.linkie.discord.utils.sendMessage
import me.shedaniel.linkie.discord.utils.tryRemoveAllReactions
import reactor.core.publisher.Mono
import java.time.Duration
import java.util.*

typealias EmbedCreator = EmbedCreateSpec.() -> Unit
typealias EmbedCreator = suspend EmbedCreateSpec.() -> Unit

fun embedCreator(creator: EmbedCreator) = creator

fun MessageCreator.sendPages(
initialPage: Int,
maxPages: Int,
creator: EmbedCreateSpec.(Int) -> Unit,
creator: suspend EmbedCreateSpec.(Int) -> Unit,
) = sendPages(initialPage, maxPages, previous.author.get().id, creator)

fun MessageCreator.sendPages(
initialPage: Int,
maxPages: Int,
user: User,
creator: EmbedCreateSpec.(Int) -> Unit,
creator: suspend EmbedCreateSpec.(Int) -> Unit,
) = sendPages(initialPage, maxPages, user.id, creator)

fun MessageCreator.sendPages(
initialPage: Int,
maxPages: Int,
userId: Snowflake,
creator: EmbedCreateSpec.(Int) -> Unit,
creator: suspend EmbedCreateSpec.(Int) -> Unit,
) {
var page = initialPage
val builder = embedCreator { creator(this, page) }
Expand Down Expand Up @@ -82,7 +90,7 @@ fun MessageCreator.sendPages(
}

interface CommandBase {
fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)
suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)

fun postRegister() {}
}
Expand Down Expand Up @@ -113,16 +121,16 @@ data class MessageCreator(

fun sendEmbed(content: EmbedCreator): Mono<Message> {
return if (message == null) {
channel.sendEmbedMessage(previous, content)
channel.sendEmbedMessage(previous) { runBlockingNoJs { content() } }
} else {
message!!.sendEditEmbed(content)
message!!.sendEditEmbed { runBlockingNoJs { content() } }
}.doOnSuccess { message = it }
}
}

open class SubCommandHolder : CommandBase {
private val subcommands = mutableMapOf<String, SubCommandBase>()
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateNotEmpty(prefix, "$cmd help")

when (val subcommand = args[0].toLowerCase(Locale.ROOT)) {
Expand Down Expand Up @@ -151,7 +159,7 @@ open class SubCommandHolder : CommandBase {
val reactor = field.get(this) as SubCommandReactor
subcommands[name] = object : SubCommandBase {
override val name: String = name
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) =
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) =
reactor.execute(event, message, prefix, user, cmd, args, channel)

}
Expand All @@ -160,13 +168,13 @@ open class SubCommandHolder : CommandBase {
}

fun subCmd(reactor: (event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) -> Unit): SubCommandReactor = object : SubCommandReactor {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
reactor(event, message, prefix, user, cmd, args, channel)
}
}

fun subCmd(reactor: CommandBase): SubCommandReactor = object : SubCommandReactor {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
reactor.execute(event, message, prefix, user, cmd, args, channel)
}
}
Expand All @@ -177,10 +185,10 @@ interface SubCommandBase : SubCommandReactor {
}

interface SubCommandReactor {
fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)
suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)
}

inline fun <T> MessageCreator.getCatching(user: User, run: () -> T): T {
inline suspend fun <T> MessageCreator.getCatching(user: User, run: suspend () -> T): T {
try {
return run()
} catch (t: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object CommandHandler : CommandAcceptor {
override fun getPrefix(event: MessageCreateEvent): String? =
event.guildId.orElse(null)?.let { ConfigManager[it.asLong()].prefix }

override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
if (cmd in commandMap)
commandMap[cmd]!!.execute(event, message, prefix, user, cmd, args, channel)
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/me/shedaniel/linkie/discord/CommandMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class CommandMap(private val commandAcceptor: CommandAcceptor, private val defau
}

interface CommandAcceptor {
fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)
suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel)
fun getPrefix(event: MessageCreateEvent): String?
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ object TrickHandler : CommandAcceptor {
override fun getPrefix(event: MessageCreateEvent): String? =
event.guildId.orElse(null)?.let { ConfigManager[it.asLong()].tricksPrefix }

override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
if (event.guildId.isPresent) {
val guildId = event.guildId.get().asLong()
if (!ConfigManager[guildId].tricksEnabled) return
Expand Down
24 changes: 14 additions & 10 deletions src/main/kotlin/me/shedaniel/linkie/discord/ValueKeeper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,45 @@

package me.shedaniel.linkie.discord

import com.soywiz.korio.async.runBlockingNoJs
import me.shedaniel.linkie.discord.utils.getOrNull
import java.time.Duration
import java.util.*
import kotlin.concurrent.timerTask
import kotlin.properties.ReadOnlyProperty

@Suppress("MemberVisibilityCanBePrivate", "unused")
class ValueKeeper<T> constructor(val timeToKeep: Duration, var value: Optional<T>, val getter: () -> T) {
class ValueKeeper<T> constructor(val timeToKeep: Duration, var value: Optional<T>, val getter: suspend () -> T) {
companion object {
private val timer = Timer()
}

private var task: TimerTask? = null

constructor(timeToKeep: Duration, value: T, getter: () -> T) : this(timeToKeep, Optional.of(value), getter)
constructor(timeToKeep: Duration, getter: () -> T) : this(timeToKeep, getter(), getter)
constructor(timeToKeep: Duration, value: T, getter: suspend () -> T) : this(timeToKeep, Optional.of(value), getter)
constructor(timeToKeep: Duration, getter: suspend () -> T) : this(timeToKeep, runBlockingNoJs { getter() }, getter)

init {
schedule()
runBlockingNoJs {
schedule()
}
}

fun get(): T = value.orElseGet { getter().also { value = Optional.of(it); schedule() } }
suspend fun get(): T = value.getOrNull() ?: getter().also { value = Optional.of(it); schedule() }

fun clear() {
suspend fun clear() {
value = Optional.empty()
System.gc()
}

fun schedule() {
suspend fun schedule() {
task?.cancel()
task = timerTask { clear() }
task = timerTask { runBlockingNoJs { clear() } }
timer.schedule(task, timeToKeep.toMillis())
}
}

fun <T> valueKeeper(timeToKeep: Duration = Duration.ofMinutes(2), getter: () -> T): ReadOnlyProperty<Any?, T> {
fun <T> valueKeeper(timeToKeep: Duration = Duration.ofMinutes(2), getter: suspend () -> T): ReadOnlyProperty<Any?, T> {
val keeper = ValueKeeper(timeToKeep, getter)
return ReadOnlyProperty { _, _ -> keeper.get() }
return ReadOnlyProperty { _, _ -> runBlockingNoJs { keeper.get() } }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import me.shedaniel.linkie.discord.utils.setTimestampToNow
import me.shedaniel.linkie.discord.validateEmpty

object AWCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
message.sendEmbed {
setFooter("Requested by " + user.discriminatedName, user.avatarUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import me.shedaniel.linkie.discord.utils.*
import me.shedaniel.linkie.discord.validateEmpty

object AboutCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
message.sendEmbed {
setTitle("About Linkie")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import me.shedaniel.linkie.discord.validateUsage
import java.util.*

object AddTrickCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
LinkieScripting.validateGuild(event)
args.validateUsage(prefix, 2..Int.MAX_VALUE, "$cmd <name> [--script] <trick>")
val name = args.first()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import me.shedaniel.linkie.discord.scripting.push
import me.shedaniel.linkie.discord.validateNotEmpty

object EvaluateCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateNotEmpty(prefix, "$cmd <script>")
var string = args.joinToString(" ")
if (string.startsWith("```")) string = string.substring(3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object FTBDramaCommand : CommandBase {
isLenient = true
}

override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
val jsonText = URL("https://ftb-drama.herokuapp.com/json").readText()
val jsonObject = json.parseToJsonElement(jsonText).jsonObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object FabricCommand : CommandBase {
version != null && version.snapshot == null
}.maxWithOrNull(compareBy { it.tryToVersion() })!!

override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateUsage(prefix, 0..1, "$cmd [version]")
val latestVersion = this.latestVersion
val gameVersion = if (args.isEmpty()) latestVersion else args[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object FabricDramaCommand : CommandBase {
isLenient = true
}

override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
val jsonText = URL("https://fabric-drama.herokuapp.com/json").readText()
val jsonObject = json.parseToJsonElement(jsonText).jsonObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import me.shedaniel.linkie.discord.utils.discriminatedName
import me.shedaniel.linkie.discord.utils.setTimestampToNow

object GetValueCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
event.validateInGuild()
event.member.get().validateAdmin()
args.validateUsage(prefix, 1, "$cmd <property>")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import me.shedaniel.linkie.discord.utils.setTimestampToNow
import me.shedaniel.linkie.discord.validateEmpty

object HelpCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
message.sendEmbed {
setTitle("Linkie Help Command")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import java.time.Instant
import kotlin.math.ceil

object ListAllTricksCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
LinkieScripting.validateGuild(event)
args.validateEmpty(prefix, cmd)
val guild = event.guild.block()!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import java.time.Instant
import kotlin.math.ceil

object ListTricksCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
LinkieScripting.validateGuild(event)
args.validateUsage(prefix, 1, "$cmd [userId]")
val memberId = if (args.isEmpty()) user.id.asLong() else (args.first().toLongOrNull() ?: throw NullPointerException("Member id must be a number!"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import me.shedaniel.linkie.discord.utils.setTimestampToNow
import me.shedaniel.linkie.discord.validateEmpty

object NamespacesCommand : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
args.validateEmpty(prefix, cmd)
message.sendEmbed {
setTitle("List of Namespaces")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger
import kotlin.math.ceil

class QueryClassCommand(private val namespace: Namespace?) : CommandBase {
override fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
override suspend fun execute(event: MessageCreateEvent, message: MessageCreator, prefix: String, user: User, cmd: String, args: MutableList<String>, channel: MessageChannel) {
if (this.namespace == null) {
args.validateUsage(prefix, 2..3, "$cmd <namespace> <search> [version]\nDo !namespaces for list of namespaces.")
} else args.validateUsage(prefix, 1..2, "$cmd <search> [version]")
Expand Down Expand Up @@ -70,7 +70,7 @@ class QueryClassCommand(private val namespace: Namespace?) : CommandBase {
}
}

private fun build(
private suspend fun build(
searchKey: String,
provider: MappingsProvider,
user: User,
Expand All @@ -89,7 +89,7 @@ class QueryClassCommand(private val namespace: Namespace?) : CommandBase {
val result = MappingsQuery.queryClasses(QueryContext(
provider = provider,
searchKey = searchKey,
)).deCompound().map { it.map { it.value }.toList() }
)).toSimpleMappingsMetadata().map { it.map { it.value }.toList() }
if (result.value.isEmpty()) {
MappingsQuery.errorNoResultsFound(MappingsEntryType.CLASS, searchKey)
}
Expand Down
Loading

0 comments on commit fa07887

Please sign in to comment.