mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 07:30:14 +08:00
Merge remote-tracking branch 'origin'
This commit is contained in:
commit
5c287faf4e
@ -166,7 +166,7 @@ internal class QQImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate", "DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
internal class MemberImpl(
|
internal class MemberImpl(
|
||||||
qq: QQImpl,
|
qq: QQImpl,
|
||||||
group: GroupImpl,
|
group: GroupImpl,
|
||||||
@ -286,6 +286,20 @@ internal class MemberImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = bot.hashCode()
|
||||||
|
result = 31 * result + id.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DuplicatedCode")
|
||||||
|
override fun equals(other: Any?): Boolean { // 不要删除. trust me
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Contact) return false
|
||||||
|
if (this::class != other::class) return false
|
||||||
|
return this.id == other.id && this.bot == other.bot
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Member($id)"
|
return "Member($id)"
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
||||||
|
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
import kotlinx.coroutines.Deferred
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.io.core.ByteReadPacket
|
import kotlinx.io.core.ByteReadPacket
|
||||||
import kotlinx.io.core.discardExact
|
import kotlinx.io.core.discardExact
|
||||||
@ -19,11 +19,10 @@ import net.mamoe.mirai.contact.MemberPermission
|
|||||||
import net.mamoe.mirai.data.MemberInfo
|
import net.mamoe.mirai.data.MemberInfo
|
||||||
import net.mamoe.mirai.data.MultiPacket
|
import net.mamoe.mirai.data.MultiPacket
|
||||||
import net.mamoe.mirai.data.Packet
|
import net.mamoe.mirai.data.Packet
|
||||||
import net.mamoe.mirai.event.ListeningStatus
|
|
||||||
import net.mamoe.mirai.event.events.BotJoinGroupEvent
|
import net.mamoe.mirai.event.events.BotJoinGroupEvent
|
||||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||||
import net.mamoe.mirai.event.events.MemberJoinEvent
|
import net.mamoe.mirai.event.events.MemberJoinEvent
|
||||||
import net.mamoe.mirai.event.subscribe
|
import net.mamoe.mirai.event.subscribingGetAsync
|
||||||
import net.mamoe.mirai.message.FriendMessage
|
import net.mamoe.mirai.message.FriendMessage
|
||||||
import net.mamoe.mirai.message.data.MessageChain
|
import net.mamoe.mirai.message.data.MessageChain
|
||||||
import net.mamoe.mirai.message.data.MessageSource
|
import net.mamoe.mirai.message.data.MessageSource
|
||||||
@ -279,17 +278,14 @@ internal class MessageSvc {
|
|||||||
override val groupId: Long,
|
override val groupId: Long,
|
||||||
override val sourceMessage: MessageChain
|
override val sourceMessage: MessageChain
|
||||||
) : MessageSource {
|
) : MessageSource {
|
||||||
lateinit var sequenceIdDeferred: CompletableDeferred<Int>
|
lateinit var sequenceIdDeferred: Deferred<Int>
|
||||||
|
|
||||||
|
@UseExperimental(MiraiExperimentalAPI::class)
|
||||||
fun startWaitingSequenceId(contact: Contact) {
|
fun startWaitingSequenceId(contact: Contact) {
|
||||||
sequenceIdDeferred = CompletableDeferred()
|
sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int> {
|
||||||
contact.subscribe<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt> { event ->
|
if (it.messageRandom == messageUid.toInt()) {
|
||||||
if (event.messageRandom == messageUid.toInt()) {
|
it.sequenceId
|
||||||
sequenceIdDeferred.complete(event.sequenceId)
|
} else null
|
||||||
return@subscribe ListeningStatus.STOPPED
|
|
||||||
}
|
|
||||||
|
|
||||||
return@subscribe ListeningStatus.LISTENING
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,9 @@ interface Member : QQ, Contact {
|
|||||||
/**
|
/**
|
||||||
* 禁言.
|
* 禁言.
|
||||||
*
|
*
|
||||||
|
* QQ 中最小操作和显示的时间都是一分钟.
|
||||||
|
* 机器人可以实现精确到秒, 会被客户端显示为 1 分钟但不影响实际禁言时间.
|
||||||
|
*
|
||||||
* 管理员可禁言成员, 群主可禁言管理员和群员.
|
* 管理员可禁言成员, 群主可禁言管理员和群员.
|
||||||
*
|
*
|
||||||
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
|
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
|
||||||
|
@ -9,3 +9,104 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.event
|
package net.mamoe.mirai.event
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
suspend inline fun <reified E : Event, R : Any> subscribingGet(
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||||
|
): R {
|
||||||
|
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||||
|
return subscribingGetOrNull(timeoutMillis, filter) ?: error("timeout subscribingGet")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起当前协程, 监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
suspend inline fun <reified E : Event, R : Any> subscribingGetOrNull(
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||||
|
): R? {
|
||||||
|
require(timeoutMillis == -1L || timeoutMillis > 0) { "timeoutMillis must be -1 or > 0" }
|
||||||
|
var result: R? = null
|
||||||
|
var resultThrowable: Throwable? = null
|
||||||
|
|
||||||
|
if (timeoutMillis == -1L) {
|
||||||
|
@Suppress("DuplicatedCode") // for better performance
|
||||||
|
coroutineScope {
|
||||||
|
var listener: Listener<E>? = null
|
||||||
|
listener = this.subscribe {
|
||||||
|
val value = try {
|
||||||
|
filter.invoke(this, it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
resultThrowable = e
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
result = value
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
} else return@subscribe ListeningStatus.LISTENING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
withTimeoutOrNull(timeoutMillis) {
|
||||||
|
var listener: Listener<E>? = null
|
||||||
|
@Suppress("DuplicatedCode") // for better performance
|
||||||
|
listener = this.subscribe {
|
||||||
|
val value = try {
|
||||||
|
filter.invoke(this, it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
resultThrowable = e
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
result = value
|
||||||
|
return@subscribe ListeningStatus.STOPPED.also { listener!!.complete() }
|
||||||
|
} else return@subscribe ListeningStatus.LISTENING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultThrowable?.let { throw it }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步监听这个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, [Deferred.await] 会抛出这个异常或.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param coroutineContext 额外的 [CoroutineContext]
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*/
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
inline fun <reified E : Event, R : Any> CoroutineScope.subscribingGetAsync(
|
||||||
|
coroutineContext: CoroutineContext = EmptyCoroutineContext,
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
noinline filter: E.(E) -> R? // 不要 crossinline: crossinline 后 stacktrace 会不正常
|
||||||
|
): Deferred<R> = this.async(coroutineContext) {
|
||||||
|
subscribingGet(timeoutMillis, filter)
|
||||||
|
}
|
@ -101,6 +101,9 @@ interface Listener<in E : Event> : CompletableJob {
|
|||||||
*
|
*
|
||||||
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
* @param coroutineContext 给事件监听协程的额外的 [CoroutineContext]
|
||||||
*
|
*
|
||||||
|
* @see subscribingGet 监听一个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
* @see subscribingGetAsync 异步监听一个事件, 并尝试从这个事件中获取一个值.
|
||||||
|
*
|
||||||
* @see subscribeAlways 一直监听
|
* @see subscribeAlways 一直监听
|
||||||
* @see subscribeOnce 只监听一次
|
* @see subscribeOnce 只监听一次
|
||||||
*
|
*
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.message
|
package net.mamoe.mirai.message
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
import net.mamoe.mirai.event.Event
|
import net.mamoe.mirai.event.Event
|
||||||
@ -44,25 +45,25 @@ class GroupMessage(
|
|||||||
* 对于好友消息事件, 这个方法将会给好友 ([subject]) 发送消息
|
* 对于好友消息事件, 这个方法将会给好友 ([subject]) 发送消息
|
||||||
* 对于群消息事件, 这个方法将会给群 ([subject]) 发送消息
|
* 对于群消息事件, 这个方法将会给群 ([subject]) 发送消息
|
||||||
*/
|
*/
|
||||||
suspend inline fun quoteReply(message: MessageChain) = reply(this.message.quote() + message)
|
suspend inline fun quoteReply(message: MessageChain): MessageReceipt<Group> = reply(this.message.quote() + message)
|
||||||
|
|
||||||
suspend inline fun quoteReply(message: Message) = reply(this.message.quote() + message)
|
suspend inline fun quoteReply(message: Message): MessageReceipt<Group> = reply(this.message.quote() + message)
|
||||||
suspend inline fun quoteReply(plain: String) = reply(this.message.quote() + plain)
|
suspend inline fun quoteReply(plain: String): MessageReceipt<Group> = reply(this.message.quote() + plain)
|
||||||
|
|
||||||
|
|
||||||
@JvmName("reply2")
|
@JvmName("reply2")
|
||||||
suspend inline fun String.quoteReply() = quoteReply(this)
|
suspend inline fun String.quoteReply(): MessageReceipt<Group> = quoteReply(this)
|
||||||
|
|
||||||
@JvmName("reply2")
|
@JvmName("reply2")
|
||||||
suspend inline fun Message.quoteReply() = quoteReply(this)
|
suspend inline fun Message.quoteReply(): MessageReceipt<Group> = quoteReply(this)
|
||||||
|
|
||||||
@JvmName("reply2")
|
@JvmName("reply2")
|
||||||
suspend inline fun MessageChain.quoteReply() = quoteReply(this)
|
suspend inline fun MessageChain.quoteReply(): MessageReceipt<Group> = quoteReply(this)
|
||||||
|
|
||||||
suspend inline fun MessageChain.recall() = group.recall(this)
|
suspend inline fun MessageChain.recall() = group.recall(this)
|
||||||
suspend inline fun MessageSource.recall() = group.recall(this)
|
suspend inline fun MessageSource.recall() = group.recall(this)
|
||||||
inline fun MessageSource.recallIn(delay: Long) = group.recallIn(this, delay)
|
inline fun MessageSource.recallIn(delay: Long): Job = group.recallIn(this, delay)
|
||||||
inline fun MessageChain.recallIn(delay: Long) = group.recallIn(this, delay)
|
inline fun MessageChain.recallIn(delay: Long): Job = group.recallIn(this, delay)
|
||||||
|
|
||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"
|
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"
|
||||||
|
@ -21,6 +21,8 @@ import net.mamoe.mirai.contact.Member
|
|||||||
import net.mamoe.mirai.contact.QQ
|
import net.mamoe.mirai.contact.QQ
|
||||||
import net.mamoe.mirai.data.Packet
|
import net.mamoe.mirai.data.Packet
|
||||||
import net.mamoe.mirai.event.events.BotEvent
|
import net.mamoe.mirai.event.events.BotEvent
|
||||||
|
import net.mamoe.mirai.event.subscribingGet
|
||||||
|
import net.mamoe.mirai.event.subscribingGetAsync
|
||||||
import net.mamoe.mirai.message.data.*
|
import net.mamoe.mirai.message.data.*
|
||||||
import net.mamoe.mirai.utils.*
|
import net.mamoe.mirai.utils.*
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
@ -109,6 +111,10 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
|
|||||||
suspend inline fun String.send() = this.toMessage().sendTo(subject)
|
suspend inline fun String.send() = this.toMessage().sendTo(subject)
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
operator fun <M : Message> get(at: Message.Key<M>): M {
|
||||||
|
return this.message[at]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建 @ 这个账号的消息. 当且仅当消息为群消息时可用. 否则将会抛出 [IllegalArgumentException]
|
* 创建 @ 这个账号的消息. 当且仅当消息为群消息时可用. 否则将会抛出 [IllegalArgumentException]
|
||||||
*/
|
*/
|
||||||
@ -134,4 +140,47 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
|
|||||||
*/
|
*/
|
||||||
suspend inline fun Image.download(): ByteReadPacket = bot.run { download() }
|
suspend inline fun Image.download(): ByteReadPacket = bot.run { download() }
|
||||||
// endregion
|
// endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断两个 [MessagePacket] 的 [MessagePacket.sender] 和 [MessagePacket.subject] 是否相同
|
||||||
|
*/
|
||||||
|
fun MessagePacket<*, *>.isContextIdenticalWith(another: MessagePacket<*, *>): Boolean {
|
||||||
|
return this.sender == another.sender && this.subject == another.subject
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起当前协程, 等待下一条 [MessagePacket.sender] 和 [MessagePacket.subject] 与 [P] 相同且通过 [筛选][filter] 的 [MessagePacket]
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
* @param filter 过滤器. 返回非 null 则代表得到了需要的值. [subscribingGet] 会返回这个值
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
suspend inline fun <reified P : MessagePacket<*, *>> P.nextMessage(
|
||||||
|
timeoutMillis: Long = -1,
|
||||||
|
crossinline filter: P.(P) -> Boolean
|
||||||
|
): P {
|
||||||
|
return subscribingGet<P, P>(timeoutMillis) {
|
||||||
|
takeIf { this.isContextIdenticalWith(this@nextMessage) }?.takeIf { filter(it, it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起当前协程, 等待下一条 [MessagePacket.sender] 和 [MessagePacket.subject] 与 [P] 相同的 [MessagePacket]
|
||||||
|
*
|
||||||
|
* 若 [filter] 抛出了一个异常, 本函数会立即抛出这个异常.
|
||||||
|
*
|
||||||
|
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制
|
||||||
|
*
|
||||||
|
* @see subscribingGetAsync 本函数的异步版本
|
||||||
|
*/
|
||||||
|
suspend inline fun <reified P : MessagePacket<*, *>> P.nextMessage(
|
||||||
|
timeoutMillis: Long = -1
|
||||||
|
): P {
|
||||||
|
return subscribingGet<P, P>(timeoutMillis) {
|
||||||
|
takeIf { this.isContextIdenticalWith(this@nextMessage) }
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,17 +16,14 @@ import net.mamoe.mirai.Bot
|
|||||||
import net.mamoe.mirai.BotAccount
|
import net.mamoe.mirai.BotAccount
|
||||||
import net.mamoe.mirai.alsoLogin
|
import net.mamoe.mirai.alsoLogin
|
||||||
import net.mamoe.mirai.contact.QQ
|
import net.mamoe.mirai.contact.QQ
|
||||||
|
import net.mamoe.mirai.contact.isOperator
|
||||||
import net.mamoe.mirai.contact.sendMessage
|
import net.mamoe.mirai.contact.sendMessage
|
||||||
import net.mamoe.mirai.event.*
|
import net.mamoe.mirai.event.*
|
||||||
import net.mamoe.mirai.message.FriendMessage
|
import net.mamoe.mirai.message.FriendMessage
|
||||||
import net.mamoe.mirai.message.GroupMessage
|
import net.mamoe.mirai.message.GroupMessage
|
||||||
import net.mamoe.mirai.message.data.AtAll
|
import net.mamoe.mirai.message.data.*
|
||||||
import net.mamoe.mirai.message.data.Image
|
import net.mamoe.mirai.message.nextMessage
|
||||||
import net.mamoe.mirai.message.data.PlainText
|
|
||||||
import net.mamoe.mirai.message.data.firstOrNull
|
|
||||||
import net.mamoe.mirai.message.sendAsImageTo
|
import net.mamoe.mirai.message.sendAsImageTo
|
||||||
import net.mamoe.mirai.qqandroid.Bot
|
|
||||||
import net.mamoe.mirai.qqandroid.QQAndroid
|
|
||||||
import net.mamoe.mirai.utils.FileBasedDeviceInfo
|
import net.mamoe.mirai.utils.FileBasedDeviceInfo
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -49,7 +46,7 @@ private fun readTestAccount(): BotAccount? {
|
|||||||
|
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
val bot = QQAndroid.Bot( // JVM 下也可以不写 `QQAndroid.` 引用顶层函数
|
val bot = Bot( // JVM 下也可以不写 `QQAndroid.` 引用顶层函数
|
||||||
123456789,
|
123456789,
|
||||||
"123456"
|
"123456"
|
||||||
) {
|
) {
|
||||||
@ -207,6 +204,25 @@ fun Bot.messageDSL() {
|
|||||||
// sender: QQ
|
// sender: QQ
|
||||||
// it: String (来自 MessageChain.toString)
|
// it: String (来自 MessageChain.toString)
|
||||||
// group: Group
|
// group: Group
|
||||||
|
|
||||||
|
case("recall") {
|
||||||
|
reply("😎").recallIn(3000) // 3 秒后自动撤回这条消息
|
||||||
|
}
|
||||||
|
|
||||||
|
case("禁言") {
|
||||||
|
// 挂起当前协程, 等待下一条满足条件的消息.
|
||||||
|
// 发送 "禁言" 后需要再发送一条消息 at 一个人.
|
||||||
|
val value: At = nextMessage { message.any(At) }[At]
|
||||||
|
value.member().mute(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
startsWith("群名=") {
|
||||||
|
if (!sender.isOperator()) {
|
||||||
|
sender.mute(5)
|
||||||
|
return@startsWith
|
||||||
|
}
|
||||||
|
group.name = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user