diff --git a/build.gradle.kts b/build.gradle.kts index c99257b..bf66cff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "io.github.samarium150" -version = "1.4.0" +version = "1.5.0" repositories { mavenLocal() diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/MiraiConsoleDriftBottle.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/MiraiConsoleDriftBottle.kt index 8fa2ce5..177d744 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/MiraiConsoleDriftBottle.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/MiraiConsoleDriftBottle.kt @@ -37,7 +37,7 @@ object MiraiConsoleDriftBottle : KotlinPlugin( JvmPluginDescription( id = "io.github.samarium150.mirai.plugin.mirai-console-drift-bottle", name = "Drift Bottle", - version = "1.4.0", + version = "1.5.0", ) { author("Samarium150") info("简单的漂流瓶插件") diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/JumpInto.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/JumpInto.kt index 21c2cb6..3bac469 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/JumpInto.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/JumpInto.kt @@ -18,11 +18,16 @@ package io.github.samarium150.mirai.plugin.driftbottle.command import io.github.samarium150.mirai.plugin.driftbottle.MiraiConsoleDriftBottle import io.github.samarium150.mirai.plugin.driftbottle.config.CommandConfig +import io.github.samarium150.mirai.plugin.driftbottle.config.GeneralConfig import io.github.samarium150.mirai.plugin.driftbottle.config.ReplyConfig import io.github.samarium150.mirai.plugin.driftbottle.data.Item import io.github.samarium150.mirai.plugin.driftbottle.data.Owner import io.github.samarium150.mirai.plugin.driftbottle.data.Sea import io.github.samarium150.mirai.plugin.driftbottle.data.Source +import io.github.samarium150.mirai.plugin.driftbottle.util.lock +import io.github.samarium150.mirai.plugin.driftbottle.util.randomDelay +import io.github.samarium150.mirai.plugin.driftbottle.util.unlock +import kotlinx.coroutines.delay import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.SimpleCommand import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors @@ -43,9 +48,10 @@ object JumpInto : SimpleCommand( @Handler suspend fun CommandSender.handle() { val sender = user - if (sender == null) + if (sender == null) randomDelay().also { sendMessage(ReplyConfig.jumpInto.replace("%num", Sea.contents.size.toString())) - else { + } else { + if (!lock(sender.id)) return val subject = subject val owner = Owner( sender.id, @@ -58,7 +64,12 @@ object JumpInto : SimpleCommand( ) else null val body = Item(Item.Type.BODY, owner, source) Sea.contents.add(body) - sendMessage(ReplyConfig.jumpInto.replace("%num", Sea.contents.size.toString())) + randomDelay().also { + sendMessage(ReplyConfig.jumpInto.replace("%num", Sea.contents.size.toString())).also { + delay(GeneralConfig.perUse * 1000L) + unlock(sender.id) + } + } } } } diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/Pickup.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/Pickup.kt index b372efa..df672c9 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/Pickup.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/Pickup.kt @@ -22,6 +22,11 @@ import io.github.samarium150.mirai.plugin.driftbottle.config.GeneralConfig import io.github.samarium150.mirai.plugin.driftbottle.config.ReplyConfig import io.github.samarium150.mirai.plugin.driftbottle.data.Item import io.github.samarium150.mirai.plugin.driftbottle.data.Sea +import io.github.samarium150.mirai.plugin.driftbottle.util.disableAt +import io.github.samarium150.mirai.plugin.driftbottle.util.lock +import io.github.samarium150.mirai.plugin.driftbottle.util.randomDelay +import io.github.samarium150.mirai.plugin.driftbottle.util.unlock +import kotlinx.coroutines.delay import net.mamoe.mirai.console.command.CommandSenderOnMessage import net.mamoe.mirai.console.command.SimpleCommand import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors @@ -41,8 +46,14 @@ object Pickup : SimpleCommand( @Suppress("unused") @Handler suspend fun CommandSenderOnMessage<*>.handle() { + val sender = fromEvent.sender + val subject = fromEvent.subject + if (!lock(sender.id)) return if (Sea.contents.size == 0) { - sendMessage(ReplyConfig.noItem) + randomDelay().also { + sendMessage(ReplyConfig.noItem) + unlock(sender.id) + } return } val index = Random().nextInt(Sea.contents.size) @@ -51,6 +62,11 @@ object Pickup : SimpleCommand( || (item.type == Item.Type.BODY && !GeneralConfig.incrementalBody) ) Sea.contents.removeAt(index) - sendMessage(item.toMessageChain(fromEvent.subject)) + randomDelay().also { + sendMessage(disableAt(item.toMessageChain(subject), subject)).also { + delay(GeneralConfig.perUse * 1000L) + unlock(sender.id) + } + } } } diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/ThrowAway.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/ThrowAway.kt index 4b7ecb9..056023b 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/ThrowAway.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/command/ThrowAway.kt @@ -24,10 +24,8 @@ import io.github.samarium150.mirai.plugin.driftbottle.data.Item import io.github.samarium150.mirai.plugin.driftbottle.data.Owner import io.github.samarium150.mirai.plugin.driftbottle.data.Sea import io.github.samarium150.mirai.plugin.driftbottle.data.Source -import io.github.samarium150.mirai.plugin.driftbottle.util.CacheType -import io.github.samarium150.mirai.plugin.driftbottle.util.ContentCensor -import io.github.samarium150.mirai.plugin.driftbottle.util.cacheFolderByType -import io.github.samarium150.mirai.plugin.driftbottle.util.saveFrom +import io.github.samarium150.mirai.plugin.driftbottle.util.* +import kotlinx.coroutines.delay import net.mamoe.mirai.console.command.CommandSenderOnMessage import net.mamoe.mirai.console.command.SimpleCommand import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors @@ -44,7 +42,6 @@ object ThrowAway : SimpleCommand( secondaryNames = CommandConfig.throwAway, description = "丢出漂流瓶" ) { - private val active = mutableSetOf() @ConsoleExperimentalApi @ExperimentalCommandDescriptors @@ -55,17 +52,20 @@ object ThrowAway : SimpleCommand( suspend fun CommandSenderOnMessage<*>.handle(vararg messages: Message = arrayOf()) { val sender = fromEvent.sender val subject = fromEvent.subject + if (!lock(sender.id)) return val chain = if (messages.isNotEmpty()) messageChainOf(*messages) else { - if (!active.add(sender.id)) return - sendMessage(ReplyConfig.waitForNextMessage) + randomDelay().also { + sendMessage(ReplyConfig.waitForNextMessage) + } runCatching { fromEvent.nextMessage(30_000) }.onFailure { sendMessage(ReplyConfig.timeoutMessage) - }.also { - active.remove(sender.id) - }.getOrNull() ?: return + }.getOrNull() ?: run { + unlock(sender.id) + return@handle + } } if (GeneralConfig.enableContentCensor) runCatching { if (!ContentCensor.determine(chain)) { @@ -93,10 +93,19 @@ object ThrowAway : SimpleCommand( val bottle = Item(Item.Type.BOTTLE, owner, source, chainJson) Sea.contents.add(bottle) val parts = ReplyConfig.throwAway.split("%content") - sendMessage(buildMessageChain { - +PlainText(parts[0]) - +chain - +PlainText(parts[1]) - }) + runCatching { + randomDelay().also { + if (parts.size == 1) sendMessage(parts[0]) + else + sendMessage(buildMessageChain { + +PlainText(parts[0]) + +disableAt(chain, subject) + +PlainText(parts[1]) + }) + } + }.also { + delay(GeneralConfig.perUse * 1000L) + unlock(sender.id) + } } } diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/AdvancedConfig.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/AdvancedConfig.kt new file mode 100644 index 0000000..09f499e --- /dev/null +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/AdvancedConfig.kt @@ -0,0 +1,11 @@ +package io.github.samarium150.mirai.plugin.driftbottle.config + +import net.mamoe.mirai.console.data.AutoSavePluginConfig +import net.mamoe.mirai.console.data.ValueDescription +import net.mamoe.mirai.console.data.value + +object AdvancedConfig : AutoSavePluginConfig("Advanced") { + + @ValueDescription("At显示为纯文本") + val disableDirectAt by value(false) +} diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/GeneralConfig.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/GeneralConfig.kt index 2f233d9..9c911e9 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/GeneralConfig.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/config/GeneralConfig.kt @@ -33,4 +33,10 @@ object GeneralConfig : AutoSavePluginConfig("General") { @ValueDescription("是否缓存漂流瓶图片到本地") val cacheImage by value(true) + + @ValueDescription("漂流瓶功能连续使用间隔 (单位: 秒)") + val perUse by value(10) + + @ValueDescription("随机延迟回复的时间区间 (单位: 毫秒)") + val randomDelayInterval: Pair by value(Pair(1000L, 1500L)) } diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/data/Item.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/data/Item.kt index 26ec4c6..69d8a0f 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/data/Item.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/data/Item.kt @@ -107,7 +107,7 @@ class Item { Date(timestamp) .toInstant() .atZone(ZoneId.of("Asia/Shanghai")) - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss O")) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ) ) ) diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/General.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/General.kt index e54ceff..d01071f 100644 --- a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/General.kt +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/General.kt @@ -1,8 +1,17 @@ package io.github.samarium150.mirai.plugin.driftbottle.util import io.github.samarium150.mirai.plugin.driftbottle.MiraiConsoleDriftBottle +import io.github.samarium150.mirai.plugin.driftbottle.config.AdvancedConfig +import io.github.samarium150.mirai.plugin.driftbottle.config.GeneralConfig import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.withContext +import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.message.data.At +import net.mamoe.mirai.message.data.MessageChain +import net.mamoe.mirai.message.data.PlainText +import net.mamoe.mirai.message.data.toMessageChain import java.io.BufferedOutputStream import java.io.File import java.io.FileOutputStream @@ -33,3 +42,22 @@ internal suspend fun File.saveFrom(url: String) = withContext(Dispatchers.IO) { } } } + +internal val randomDelay: suspend () -> Unit = { + val (low, high) = GeneralConfig.randomDelayInterval + if (low <= high) + delay((low..high).random()) +} + +internal fun disableAt(messageChain: MessageChain, subject: Contact): MessageChain { + return if (AdvancedConfig.disableDirectAt) { + val group = if (subject is Group) subject else null + val chain = messageChain.toMutableList() + for (i in 0 until chain.size) { + val message = chain[i] + if (message is At) + chain[i] = PlainText(message.getDisplay(group).replace("@", "At(").plus(")")) + } + chain.toMessageChain() + } else messageChain +} diff --git a/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/Throttle.kt b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/Throttle.kt new file mode 100644 index 0000000..29b4193 --- /dev/null +++ b/src/main/kotlin/io/github/samarium150/mirai/plugin/driftbottle/util/Throttle.kt @@ -0,0 +1,17 @@ +package io.github.samarium150.mirai.plugin.driftbottle.util + +import kotlinx.coroutines.sync.Mutex + +private val throttleMap = mutableMapOf() + +private fun getLock(id: Long): Mutex { + return throttleMap.getOrPut(id) { Mutex() } +} + +fun lock(id: Long): Boolean { + return getLock(id).tryLock() +} + +fun unlock(id: Long) { + throttleMap.remove(id)?.unlock() +}