From e2d04f71132e7ea67a9949f7b5174a9ccaf9c68f Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 2 Nov 2019 01:12:03 +0800 Subject: [PATCH] Add EmptyMessageChain and more extensions --- .../kotlin/net.mamoe.mirai/contact/Contact.kt | 28 ++- .../event/MessageSubscribers.kt | 2 +- .../kotlin/net.mamoe.mirai/message/Message.kt | 180 +++++++++++++++--- .../net.mamoe.mirai/message/Messages.kt | 28 --- .../tim/packet/event/ServerEventPackets.kt | 1 + 5 files changed, 165 insertions(+), 74 deletions(-) delete mode 100644 mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt index 0b06547e0..9535841b7 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt @@ -5,8 +5,7 @@ package net.mamoe.mirai.contact import net.mamoe.mirai.Bot import net.mamoe.mirai.message.Message import net.mamoe.mirai.message.MessageChain -import net.mamoe.mirai.message.PlainText -import net.mamoe.mirai.message.toChain +import net.mamoe.mirai.message.singleChain import net.mamoe.mirai.network.BotSession import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler import net.mamoe.mirai.withSession @@ -25,13 +24,11 @@ sealed class Contact(val bot: Bot, val id: UInt) { abstract suspend fun sendMessage(message: MessageChain) - abstract suspend fun sendXMLMessage(message: String) + //这两个方法应写为扩展函数, 但为方便 import 还是写在这里 + suspend fun sendMessage(plain: String) = sendMessage(plain.singleChain()) - //这两个方法写在 Contact 里面更适合. 因为 import 不便 - suspend fun sendMessage(plain: String) = sendMessage(PlainText(plain)) - - suspend fun sendMessage(message: Message) = sendMessage(message.toChain()) + suspend fun sendMessage(message: Message) = sendMessage(message.singleChain()) } /** @@ -75,14 +72,10 @@ class Group internal constructor(bot: Bot, val groupId: GroupId) : Contact(bot, bot.network[EventPacketHandler].sendGroupMessage(this, message) } - override suspend fun sendXMLMessage(message: String) { - - } - companion object } -inline fun Group.withSession(block: BotSession.() -> R): R = bot.withSession(block) +inline fun Contact.withSession(block: BotSession.() -> R): R = bot.withSession(block) /** * QQ 对象. @@ -93,12 +86,17 @@ inline fun Group.withSession(block: BotSession.() -> R): R = bot.withSession * * @author Him188moe */ -class QQ internal constructor(bot: Bot, id: UInt) : Contact(bot, id) { +open class QQ internal constructor(bot: Bot, id: UInt) : Contact(bot, id) { override suspend fun sendMessage(message: MessageChain) { bot.network[EventPacketHandler].sendFriendMessage(this, message) } +} - override suspend fun sendXMLMessage(message: String) { - TODO() +/** + * 群成员 + */ +class Member internal constructor(bot: Bot, id: UInt, val group: Group) : QQ(bot, id) { + init { + TODO("Group member implementation") } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt index a5ed04f55..a580063c5 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt @@ -36,7 +36,7 @@ abstract class SenderAndMessage( */ suspend inline fun reply(message: MessageChain) = subject.sendMessage(message) - suspend fun reply(message: Message) = subject.sendMessage(message.toChain()) + suspend fun reply(message: Message) = subject.sendMessage(message.singleChain()) suspend fun reply(plain: String) = subject.sendMessage(plain.toMessage()) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt index 528c51f67..fc59edfcb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt @@ -107,6 +107,7 @@ interface Message { * 将 [this] 发送给指定联系人 */ suspend inline fun Message.sendTo(contact: Contact) = contact.sendMessage(this) + // endregion // region PlainText @@ -118,6 +119,22 @@ inline class PlainText(override val stringValue: String) : Message { companion object Key : Message.Key } + +/** + * 构造 [PlainText] + */ +fun String.toMessage(): PlainText = PlainText(this) + +/** + * 得到包含作为 [PlainText] 的 [this] 的 [MessageChain]. + * + * @return 唯一成员且不可修改的 [SingleMessageChainImpl] + * + * @see SingleMessageChain + * @see SingleMessageChainImpl + */ +fun String.singleChain(): MessageChain = this.toMessage().singleChain() + // endregion // region Image @@ -231,7 +248,26 @@ fun SingleMessageChain(delegate: Message): MessageChain { } // endregion -// region extensions +// region extensions for MessageChain + +/** + * 得到包含 [this] 的 [MessageChain]. + * 若 [this] 为 [MessageChain] 将直接返回 this + * 否则将调用 [SingleMessageChain] 构造一个唯一成员且不可修改的 [SingleMessageChainImpl] + * + * @see SingleMessageChain + * @see SingleMessageChainImpl + */ +fun Message.singleChain(): MessageChain = if (this is MessageChain) this else SingleMessageChain(this) + +@Deprecated(message = "deprected", replaceWith = ReplaceWith("this.singleChain()"), level = DeprecationLevel.WARNING) +fun Message.toChain(): MessageChain = singleChain() + +/** + * 构造 [MessageChain] + */ +fun List<Message>.toMessageChain(): MessageChain = MessageChain(this) + /** * 获取第一个 [M] 类型的 [Message] 实例 @@ -249,6 +285,7 @@ inline fun <reified M : Message> MessageChain.first(): Message = this.first { M: */ inline fun <reified M : Message> MessageChain.any(): Boolean = this.firstOrNull { M::class.isInstance(it) } !== null + /** * 获取第一个 [M] 类型的 [Message] 实例 */ @@ -299,7 +336,7 @@ interface MessageChain : Message, MutableList<Message> { } operator fun plusAssign(plain: String) { - this.concat(plain.toMessage()) + this.plusAssign(plain.toMessage()) } /** @@ -311,6 +348,71 @@ interface MessageChain : Message, MutableList<Message> { operator fun <M : Message> get(key: Message.Key<M>): M = first(key) } +/** + * 空的 [Message]. + * + * 它不包含任何元素, 但维护一个 'lazy' 的 [delegate]. + * + * 只有在必要的时候才会创建 list, 如迭代([iterator]), 插入([add]), 连接([concat], [plus], [plusAssign])时. + * + * 它是一个正常的 [Message] 和 [Message]. 可以做所有 [Message] 能做的事. + */ +class EmptyMessageChain : MessageChain { + private val delegate: MessageChainImpl by lazy { MessageChainImpl() } + private inline val initialized: Boolean get() = (::delegate as Lazy<*>).isInitialized() + + override fun subList(fromIndex: Int, toIndex: Int): MutableList<Message> = + if (initialized) delegate.subList( + fromIndex, + toIndex + ) else throw IndexOutOfBoundsException("given args that from $fromIndex to $toIndex, but the list is empty") + + override val stringValue: String + get() = if (initialized) delegate.stringValue else "" + + override fun toString(): String = stringValue + + override fun contains(sub: String): Boolean = if (initialized) delegate.contains(sub) else false + override fun contains(element: Message): Boolean = if (initialized) delegate.contains(element) else false + override fun concat(tail: Message): MessageChain = delegate.concat(tail) + + override val size: Int = if (initialized) delegate.size else 0 + override fun containsAll(elements: Collection<Message>): Boolean = + if (initialized) delegate.containsAll(elements) else false + + override fun get(index: Int): Message = + if (initialized) delegate[index] else throw IndexOutOfBoundsException(index.toString()) + + override fun indexOf(element: Message): Int = if (initialized) delegate.indexOf(element) else -1 + override fun isEmpty(): Boolean = if (initialized) delegate.isEmpty() else true + override fun iterator(): MutableIterator<Message> = delegate.iterator() + + override fun lastIndexOf(element: Message): Int = if (initialized) delegate.lastIndexOf(element) else -1 + override fun add(element: Message): Boolean = delegate.add(element) + override fun add(index: Int, element: Message) = delegate.add(index, element) + override fun addAll(index: Int, elements: Collection<Message>): Boolean = delegate.addAll(elements) + override fun addAll(elements: Collection<Message>): Boolean = delegate.addAll(elements) + override fun clear() { + if (initialized) delegate.clear() + } + + override fun listIterator(): MutableListIterator<Message> = delegate.listIterator() + + override fun listIterator(index: Int): MutableListIterator<Message> = delegate.listIterator() + override fun remove(element: Message): Boolean = if (initialized) delegate.remove(element) else false + override fun removeAll(elements: Collection<Message>): Boolean = + if (initialized) delegate.removeAll(elements) else false + + override fun removeAt(index: Int): Message = + if (initialized) delegate.removeAt(index) else throw IndexOutOfBoundsException(index.toString()) + + override fun retainAll(elements: Collection<Message>): Boolean = + if (initialized) delegate.retainAll(elements) else false + + override fun set(index: Int, element: Message): Message = + if (initialized) delegate.set(index, element) else throw IndexOutOfBoundsException(index.toString()) +} + /** * Null 的 [MessageChain]. * 它不包含任何元素, 也没有创建任何 list. @@ -335,44 +437,56 @@ object NullMessageChain : MessageChain { override fun get(index: Int): Message = throw NoSuchElementException() override fun indexOf(element: Message): Int = -1 override fun isEmpty(): Boolean = true - override fun iterator(): MutableIterator<Message> = object : MutableIterator<Message> { - override fun hasNext(): Boolean = false - override fun next(): Message = throw NoSuchElementException() - override fun remove() = throw NoSuchElementException() - } + override fun iterator(): MutableIterator<Message> = EmptyMutableIterator() override fun lastIndexOf(element: Message): Int = -1 override fun add(element: Message): Boolean = unsupported() - override fun add(index: Int, element: Message) = unsupported() - override fun addAll(index: Int, elements: Collection<Message>): Boolean = unsupported() + override fun add(index: Int, element: Message) = throw IndexOutOfBoundsException(index.toString()) + override fun addAll(index: Int, elements: Collection<Message>): Boolean = + throw IndexOutOfBoundsException(index.toString()) + override fun addAll(elements: Collection<Message>): Boolean = unsupported() override fun clear() {} - override fun listIterator(): MutableListIterator<Message> = object : MutableListIterator<Message> { - override fun hasPrevious(): Boolean = false - override fun nextIndex(): Int = -1 - override fun previous(): Message = throw NoSuchElementException() - override fun previousIndex(): Int = -1 - override fun add(element: Message) = unsupported() - override fun hasNext(): Boolean = false - override fun next(): Message = throw NoSuchElementException() - override fun remove() = throw NoSuchElementException() - override fun set(element: Message) = unsupported() - } + override fun listIterator(): MutableListIterator<Message> = EmptyMutableListIterator() + + override fun listIterator(index: Int): MutableListIterator<Message> = + throw IndexOutOfBoundsException(index.toString()) - override fun listIterator(index: Int): MutableListIterator<Message> = unsupported() override fun remove(element: Message): Boolean = false override fun removeAll(elements: Collection<Message>): Boolean = false - override fun removeAt(index: Int): Message = throw NoSuchElementException() + override fun removeAt(index: Int): Message = throw IndexOutOfBoundsException(index.toString()) override fun retainAll(elements: Collection<Message>): Boolean = false - override fun set(index: Int, element: Message): Message = unsupported() + override fun set(index: Int, element: Message): Message = throw IndexOutOfBoundsException(index.toString()) private fun unsupported(): Nothing = throw UnsupportedOperationException() } +// endregion + +// region internal // ============================================================================== // ================================== INTERNAL ================================== // ============================================================================== +@Suppress("FunctionName") +private fun <E> EmptyMutableIterator(): MutableIterator<E> = object : MutableIterator<E> { + override fun hasNext(): Boolean = false + override fun next(): E = throw NoSuchElementException() + override fun remove() = throw NoSuchElementException() +} + +@Suppress("FunctionName") +private fun <E> EmptyMutableListIterator(): MutableListIterator<E> = object : MutableListIterator<E> { + override fun hasPrevious(): Boolean = false + override fun nextIndex(): Int = -1 + override fun previous(): E = throw NoSuchElementException() + override fun previousIndex(): Int = -1 + override fun add(element: E) = throw UnsupportedOperationException() + override fun hasNext(): Boolean = false + override fun next(): E = throw NoSuchElementException() + override fun remove() = throw NoSuchElementException() + override fun set(element: E) = throw UnsupportedOperationException() +} /** * [MessageChain] 实现 @@ -431,7 +545,8 @@ internal inline class MessageChainImpl constructor( /** * 单个成员的不可修改的 [MessageChain]. - * 在连接时将会把它当做一个普通 [Message] 看待. + * + * 在连接时将会把它当做一个普通 [Message] 看待, 但它不能被 [plusAssign] */ internal inline class SingleMessageChainImpl( private val delegate: Message @@ -441,14 +556,16 @@ internal inline class SingleMessageChainImpl( override val stringValue: String get() = this.delegate.stringValue override operator fun contains(sub: String): Boolean = delegate.contains(sub) - override fun concat(tail: Message): MessageChain { - if (tail is MessageChain) tail.forEach { child -> this.concat(child) } + override fun concat(tail: Message): MessageChain = + if (tail is MessageChain) tail.apply { concat(delegate) } else MessageChain(delegate, tail) - return this - } + + override fun plusAssign(message: Message) = + throw UnsupportedOperationException("SingleMessageChainImpl cannot be plusAssigned") override fun toString(): String = stringValue // endregion + // region MutableList override override fun containsAll(elements: Collection<Message>): Boolean = elements.all { it === delegate } @@ -484,7 +601,9 @@ internal inline class SingleMessageChainImpl( override fun set(element: Message) = throw UnsupportedOperationException() } - override fun listIterator(index: Int): MutableListIterator<Message> = if (index == 0) listIterator() else throw UnsupportedOperationException() + override fun listIterator(index: Int): MutableListIterator<Message> = + if (index == 0) listIterator() else throw UnsupportedOperationException() + override fun remove(element: Message): Boolean = throw UnsupportedOperationException() override fun removeAll(elements: Collection<Message>): Boolean = throw UnsupportedOperationException() override fun removeAt(index: Int): Message = throw UnsupportedOperationException() @@ -514,4 +633,5 @@ internal inline class SingleMessageChainImpl( override operator fun contains(element: Message): Boolean = element === delegate override val size: Int get() = 1 // endregion -} \ No newline at end of file +} +// endregion \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt deleted file mode 100644 index 156ad3ae1..000000000 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Messages.kt +++ /dev/null @@ -1,28 +0,0 @@ -package net.mamoe.mirai.message - -// Message 扩展方法 -/** - * 构造 [PlainText] - */ -fun String.toMessage(): PlainText = PlainText(this) - -/** - * 得到包含 [this] 的 [MessageChain]. - * 若 [this] 为 [MessageChain] 将直接返回 this - * 否则将调用 [SingleMessageChain] 构造一个唯一成员不可修改的 [SingleMessageChainImpl] - * - * @see SingleMessageChain - * @see SingleMessageChainImpl - */ -fun Message.toChain(): MessageChain = if (this is MessageChain) this else SingleMessageChain(this) - -/** - * 以 [this] 为代表 (delegate) 构造 [SingleMessageChain]. - * @throws IllegalArgumentException 当 [this] 为 [MessageChain] 的实例时 - */ -fun Message.singleChain(): MessageChain = SingleMessageChain(this) - -/** - * 构造 [MessageChain] - */ -fun List<Message>.toMessageChain(): MessageChain = MessageChain(this) \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/ServerEventPackets.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/ServerEventPackets.kt index fa606aec0..b798842e2 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/ServerEventPackets.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/ServerEventPackets.kt @@ -124,6 +124,7 @@ class IgnoredServerEventPacket(input: ByteReadPacket, eventIdentity: EventPacket * Unknown event */ class UnknownServerEventPacket( + @Suppress("MemberVisibilityCanBePrivate") val eventId: ByteArray, private val showData: Boolean = false, input: ByteReadPacket,