mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-25 06:50:09 +08:00
[Review] MessageSourceBuilder
This commit is contained in:
parent
3e4d279bcc
commit
1a1eb0e2a4
@ -59,6 +59,12 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
@MiraiInternalApi
|
||||
public val Http: HttpClient
|
||||
|
||||
public fun getUin(contactOrBot: ContactOrBot): Long {
|
||||
return if (contactOrBot is Group)
|
||||
calculateGroupUinByGroupCode(contactOrBot.id)
|
||||
else contactOrBot.id
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 groupCode 计算 groupUin. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.
|
||||
*/
|
||||
@ -137,15 +143,11 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @param ids 即 [MessageSource.ids]
|
||||
* @param internalIds 即 [MessageSource.internalIds]
|
||||
*
|
||||
* @param fromUin 为用户时为 [Friend.id], 为群时需使用 [IMirai.calculateGroupUinByGroupCode] 计算
|
||||
* @param targetUin 为用户时为 [Friend.id], 为群时需使用 [IMirai.calculateGroupUinByGroupCode] 计算
|
||||
*/
|
||||
@MiraiExperimentalApi("This is very experimental and is subject to change.")
|
||||
public fun constructMessageSource(
|
||||
botId: Long,
|
||||
kind: MessageSourceKind,
|
||||
fromUin: Long, targetUin: Long,
|
||||
fromId: Long, targetId: Long,
|
||||
ids: IntArray, time: Int, internalIds: IntArray,
|
||||
originalMessage: MessageChain
|
||||
): OfflineMessageSource
|
||||
|
@ -66,7 +66,7 @@ import net.mamoe.mirai.utils.safeCast
|
||||
* @see OnlineMessageSource 在线消息的 [MessageSource]
|
||||
* @see OfflineMessageSource 离线消息的 [MessageSource]
|
||||
*
|
||||
* @see buildMessageSource 构造一个 [OfflineMessageSource]
|
||||
* @see buildMessageSource 构建一个 [OfflineMessageSource]
|
||||
*/
|
||||
@Serializable(MessageSource.Serializer::class)
|
||||
public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle {
|
||||
@ -445,6 +445,8 @@ public sealed class OnlineMessageSource : MessageSource() {
|
||||
* 此消息源可能来自一条与机器人无关的消息. 因此无法提供对象化的 `sender` 或 `target` 获取.
|
||||
*
|
||||
* @see buildMessageSource 构建一个 [OfflineMessageSource]
|
||||
* @see IMirai.constructMessageSource
|
||||
* @see OnlineMessageSource.toOffline
|
||||
*/
|
||||
public abstract class OfflineMessageSource : MessageSource() {
|
||||
public companion object Key :
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
@ -14,14 +14,12 @@
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.IMirai
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutFriend
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutGroup
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutTemp
|
||||
import net.mamoe.mirai.contact.ContactOrBot
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.quote
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.recall
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.message.data.MessageSourceBuilder.Companion.create
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
|
||||
/**
|
||||
@ -29,7 +27,7 @@ import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
*/
|
||||
@JvmName("toOfflineMessageSource")
|
||||
public fun OnlineMessageSource.toOffline(): OfflineMessageSource =
|
||||
OfflineMessageSourceByOnline(this)
|
||||
Mirai.constructMessageSource(botId, kind, fromId, targetId, ids, time, internalIds, originalMessage)
|
||||
|
||||
///////////////
|
||||
//// AMEND ////
|
||||
@ -41,24 +39,27 @@ public fun OnlineMessageSource.toOffline(): OfflineMessageSource =
|
||||
*
|
||||
* @see buildMessageSource 查看更多说明
|
||||
*/
|
||||
@MiraiExperimentalApi
|
||||
@JvmName("copySource")
|
||||
public fun MessageSource.copyAmend(
|
||||
block: MessageSourceAmender.() -> Unit
|
||||
): OfflineMessageSource = toMutableOffline().apply(block)
|
||||
): OfflineMessageSource = MessageSourceAmender(this).apply(block).run {
|
||||
Mirai.constructMessageSource(botId, kind, fromId, targetId, ids, time, internalIds, originalMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅于 [copyAmend] 中修改 [MessageSource]
|
||||
*/
|
||||
public interface MessageSourceAmender {
|
||||
public var kind: MessageSourceKind
|
||||
public var fromUin: Long
|
||||
public var targetUin: Long
|
||||
public var ids: IntArray
|
||||
public var time: Int
|
||||
public var internalIds: IntArray
|
||||
public class MessageSourceAmender internal constructor(
|
||||
origin: MessageSource,
|
||||
) : MessageSourceBuilder() {
|
||||
public var kind: MessageSourceKind = origin.kind
|
||||
public var originalMessage: MessageChain = origin.originalMessage
|
||||
|
||||
public var originalMessage: MessageChain
|
||||
public override var fromId: Long = origin.fromId
|
||||
public override var targetId: Long = origin.targetId
|
||||
public override var ids: IntArray = origin.ids
|
||||
public override var time: Int = origin.time
|
||||
public override var internalIds: IntArray = origin.internalIds
|
||||
|
||||
/** 从另一个 [MessageSource] 中复制 [ids], [internalIds], [time]*/
|
||||
public fun metadataFrom(another: MessageSource) {
|
||||
@ -78,8 +79,8 @@ public interface MessageSourceAmender {
|
||||
* 构建一个 [OfflineMessageSource]
|
||||
*
|
||||
* ### 参数
|
||||
* 一个 [OfflineMessageSource] 须要以下参数:
|
||||
* - 发送人和发送目标: 通过 [MessageSourceBuilder.sendTo] 设置
|
||||
* 一个 [OfflineMessageSource] 需要以下参数:
|
||||
* - 发送人和发送目标: 通过 [MessageSourceBuilder.sender], [MessageSourceBuilder.target] 设置
|
||||
* - 消息元数据 (即 [MessageSource.ids], [MessageSource.internalIds], [MessageSource.time])
|
||||
* 元数据用于 [撤回][MessageSource.recall], [引用回复][MessageSource.quote], 和官方客户端定位原消息.
|
||||
* 可通过 [MessageSourceBuilder.ids], [MessageSourceBuilder.time], [MessageSourceBuilder.internalIds] 设置
|
||||
@ -92,8 +93,9 @@ public interface MessageSourceAmender {
|
||||
*
|
||||
* ### 实例
|
||||
* ```
|
||||
* bot.buildMessageSource {
|
||||
* bot sendTo target // 指定发送人和发送目标
|
||||
* bot.buildMessageSource(MessageSourceKind.GROUP) {
|
||||
* from(bot)
|
||||
* target(target)
|
||||
* metadata(source) // 从另一个消息源复制 ids, internalIds, time
|
||||
*
|
||||
* messages { // 指定消息内容
|
||||
@ -101,40 +103,49 @@ public interface MessageSourceAmender {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @see copyAmend
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@MiraiExperimentalApi
|
||||
public fun Bot.buildMessageSource(block: MessageSourceBuilder.() -> Unit): MessageSource {
|
||||
val builder = MessageSourceBuilderImpl().apply(block)
|
||||
return Mirai.constructMessageSource(
|
||||
this.id,
|
||||
builder.kind ?: error("You must call `Contact.sendTo(Contact)` when `buildMessageSource`"),
|
||||
builder.fromUin,
|
||||
builder.targetUin,
|
||||
builder.ids,
|
||||
builder.time,
|
||||
builder.internalIds,
|
||||
builder.originalMessages.build()
|
||||
)
|
||||
public fun IMirai.buildMessageSource(
|
||||
botId: Long,
|
||||
kind: MessageSourceKind,
|
||||
block: MessageSourceBuilder.() -> Unit
|
||||
): OfflineMessageSource = MessageSourceBuilder.create().apply(block).run {
|
||||
Mirai.constructMessageSource(botId, kind, fromId, targetId, ids, time, internalIds, originalMessages.build())
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建一个 [OfflineMessageSource]
|
||||
*
|
||||
* @see buildMessageSource
|
||||
*/
|
||||
public abstract class MessageSourceBuilder {
|
||||
internal abstract var kind: MessageSourceKind?
|
||||
internal abstract var fromUin: Long
|
||||
internal abstract var targetUin: Long
|
||||
public fun Bot.buildMessageSource(
|
||||
kind: MessageSourceKind,
|
||||
block: MessageSourceBuilder.() -> Unit
|
||||
): OfflineMessageSource = Mirai.buildMessageSource(this.id, kind, block)
|
||||
|
||||
internal abstract var ids: IntArray
|
||||
internal abstract var time: Int
|
||||
internal abstract var internalIds: IntArray
|
||||
|
||||
/**
|
||||
* @see buildMessageSource
|
||||
* @see create
|
||||
*/
|
||||
public open class MessageSourceBuilder internal constructor() {
|
||||
public open var fromId: Long = 0
|
||||
public open var targetId: Long = 0
|
||||
|
||||
public open var ids: IntArray = intArrayOf()
|
||||
|
||||
/**
|
||||
* seconds
|
||||
* @see MessageSource.time
|
||||
*/
|
||||
public open var time: Int = currentTimeSeconds().toInt()
|
||||
public open var internalIds: IntArray = intArrayOf()
|
||||
|
||||
@PublishedApi
|
||||
internal val originalMessages: MessageChainBuilder = MessageChainBuilder()
|
||||
|
||||
public fun time(from: MessageSource): MessageSourceBuilder = apply { this.time = from.time }
|
||||
public val now: Int get() = currentTimeSeconds().toInt()
|
||||
public fun time(value: Int): MessageSourceBuilder = apply { this.time = value }
|
||||
|
||||
public fun internalId(from: MessageSource): MessageSourceBuilder = apply { this.internalIds = from.internalIds }
|
||||
@ -158,11 +169,10 @@ public abstract class MessageSourceBuilder {
|
||||
* 从另一个 [MessageSource] 复制所有信息, 包括消息内容. 不会清空已有消息.
|
||||
*/
|
||||
public fun allFrom(source: MessageSource): MessageSourceBuilder {
|
||||
this.kind = determineKind(source)
|
||||
this.ids = source.ids
|
||||
this.time = source.time
|
||||
this.fromUin = source.fromId
|
||||
this.targetUin = source.targetId
|
||||
this.fromId = source.fromId
|
||||
this.targetId = source.targetId
|
||||
this.internalIds = source.internalIds
|
||||
this.originalMessages.addAll(source.originalMessage)
|
||||
return this
|
||||
@ -194,101 +204,38 @@ public abstract class MessageSourceBuilder {
|
||||
public fun clearMessages(): MessageSourceBuilder = apply { this.originalMessages.clear() }
|
||||
|
||||
/**
|
||||
* 设置 [发送人][this] 和 [发送目标][target], 并自动判断 [kind]
|
||||
* 设置发信人
|
||||
*/
|
||||
@JvmSynthetic
|
||||
public abstract infix fun ContactOrBot.sendTo(target: ContactOrBot): MessageSourceBuilder
|
||||
public fun sender(sender: ContactOrBot): MessageSourceBuilder = apply {
|
||||
this.fromId = Mirai.getUin(sender)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IMirai.getUin
|
||||
*/
|
||||
public fun sender(uin: Long): MessageSourceBuilder = apply {
|
||||
this.fromId = uin
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置发信目标
|
||||
*/
|
||||
public fun target(target: ContactOrBot): MessageSourceBuilder = apply {
|
||||
this.targetId = Mirai.getUin(target)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IMirai.getUin
|
||||
*/
|
||||
public fun target(uin: Long): MessageSourceBuilder = apply {
|
||||
this.targetId = uin
|
||||
}
|
||||
|
||||
public fun setSenderAndTarget(sender: ContactOrBot, target: ContactOrBot): MessageSourceBuilder =
|
||||
sender sendTo target
|
||||
}
|
||||
sender(sender).target(target)
|
||||
|
||||
|
||||
//////////////////
|
||||
//// INTERNAL ////
|
||||
//////////////////
|
||||
|
||||
|
||||
internal class MessageSourceBuilderImpl : MessageSourceBuilder() {
|
||||
override var kind: MessageSourceKind? = null
|
||||
override var fromUin: Long = 0
|
||||
override var targetUin: Long = 0
|
||||
|
||||
override var ids: IntArray = intArrayOf()
|
||||
override var time: Int = currentTimeSeconds().toInt()
|
||||
override var internalIds: IntArray = intArrayOf()
|
||||
|
||||
@JvmSynthetic
|
||||
override fun ContactOrBot.sendTo(target: ContactOrBot): MessageSourceBuilder {
|
||||
fromUin = if (this is Group) {
|
||||
Mirai.calculateGroupUinByGroupCode(this.id)
|
||||
} else this.id
|
||||
|
||||
targetUin = if (target is Group) {
|
||||
Mirai.calculateGroupUinByGroupCode(target.id)
|
||||
} else target.id
|
||||
|
||||
check(this != target) { "sender and target mustn't be the same" }
|
||||
|
||||
kind = when {
|
||||
this is Group || target is Group -> MessageSourceKind.GROUP
|
||||
this is Member || target is Member -> MessageSourceKind.TEMP
|
||||
this is Bot && target is Friend -> MessageSourceKind.FRIEND
|
||||
this is Friend && target is Bot -> MessageSourceKind.FRIEND
|
||||
this is Stranger || target is Stranger -> MessageSourceKind.STRANGER
|
||||
else -> throw IllegalArgumentException("Cannot determine source kind for sender $this and target $target")
|
||||
}
|
||||
return this@MessageSourceBuilderImpl
|
||||
public companion object {
|
||||
@JvmStatic
|
||||
public fun create(): MessageSourceBuilder = MessageSourceBuilder()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JvmSynthetic
|
||||
internal fun MessageSource.toMutableOffline(): MutableOfflineMessageSourceByOnline =
|
||||
MutableOfflineMessageSourceByOnline(this)
|
||||
|
||||
internal class MutableOfflineMessageSourceByOnline(
|
||||
origin: MessageSource
|
||||
) : OfflineMessageSource(), MessageSourceAmender {
|
||||
override var kind: MessageSourceKind = determineKind(origin)
|
||||
override var fromUin: Long
|
||||
get() = fromId
|
||||
set(value) {
|
||||
fromId = value
|
||||
}
|
||||
override var targetUin: Long
|
||||
get() = targetId
|
||||
set(value) {
|
||||
targetId = value
|
||||
}
|
||||
override val botId: Long = origin.botId
|
||||
override var ids: IntArray = origin.ids
|
||||
override var internalIds: IntArray = origin.internalIds
|
||||
override var time: Int = origin.time
|
||||
override var fromId: Long = origin.fromId
|
||||
override var targetId: Long = origin.targetId
|
||||
override var originalMessage: MessageChain = origin.originalMessage
|
||||
}
|
||||
|
||||
private fun determineKind(source: MessageSource): MessageSourceKind {
|
||||
return when {
|
||||
source.isAboutGroup() -> MessageSourceKind.GROUP
|
||||
source.isAboutFriend() -> MessageSourceKind.FRIEND
|
||||
source.isAboutTemp() -> MessageSourceKind.TEMP
|
||||
else -> error("stub")
|
||||
}
|
||||
}
|
||||
|
||||
internal class OfflineMessageSourceByOnline(
|
||||
private val onlineMessageSource: OnlineMessageSource
|
||||
) : OfflineMessageSource() {
|
||||
override val kind: MessageSourceKind
|
||||
get() = onlineMessageSource.kind
|
||||
override val botId: Long get() = onlineMessageSource.botId
|
||||
override val ids: IntArray get() = onlineMessageSource.ids
|
||||
override val internalIds: IntArray get() = onlineMessageSource.internalIds
|
||||
override val time: Int get() = onlineMessageSource.time
|
||||
override val fromId: Long get() = onlineMessageSource.fromId
|
||||
override val targetId: Long get() = onlineMessageSource.targetId
|
||||
override val originalMessage: MessageChain get() = onlineMessageSource.originalMessage
|
||||
}
|
||||
}
|
@ -892,14 +892,14 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
|
||||
override fun constructMessageSource(
|
||||
botId: Long,
|
||||
kind: MessageSourceKind,
|
||||
fromUin: Long,
|
||||
targetUin: Long,
|
||||
fromId: Long,
|
||||
targetId: Long,
|
||||
ids: IntArray,
|
||||
time: Int,
|
||||
internalIds: IntArray,
|
||||
originalMessage: MessageChain
|
||||
): OfflineMessageSource = OfflineMessageSourceImplData(
|
||||
kind, ids, botId, time, fromUin, targetUin, originalMessage, internalIds
|
||||
kind, ids, botId, time, fromId, targetId, originalMessage, internalIds
|
||||
)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user