Prechádzať zdrojové kódy

Migrate more transformers to `NoticeProcessorPipeline`

Him188 4 rokov pred
rodič
commit
edf1bc9a2e
21 zmenil súbory, kde vykonal 427 pridanie a 272 odobranie
  1. 4 2
      buildSrc/src/main/kotlin/ProjectConfigure.kt
  2. 4 1
      mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt
  3. 16 6
      mirai-core/src/commonMain/kotlin/QQAndroidBot.kt
  4. 1 1
      mirai-core/src/commonMain/kotlin/contact/AbstractMember.kt
  5. 1 1
      mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt
  6. 1 3
      mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt
  7. 6 0
      mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt
  8. 1 1
      mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt
  9. 18 13
      mirai-core/src/commonMain/kotlin/network/components/NoticeProcessorPipeline.kt
  10. 1 1
      mirai-core/src/commonMain/kotlin/network/notice/NewContactSupport.kt
  11. 34 0
      mirai-core/src/commonMain/kotlin/network/notice/decoders/GroupNotificationDecoder.kt
  12. 36 7
      mirai-core/src/commonMain/kotlin/network/notice/decoders/MsgInfoDecoder.kt
  13. 7 5
      mirai-core/src/commonMain/kotlin/network/notice/group/GroupMessageProcessor.kt
  14. 213 0
      mirai-core/src/commonMain/kotlin/network/notice/group/GroupNotificationProcessor.kt
  15. 12 14
      mirai-core/src/commonMain/kotlin/network/notice/group/GroupOrMemberListNoticeProcessor.kt
  16. 45 0
      mirai-core/src/commonMain/kotlin/network/notice/group/GroupRecallProcessor.kt
  17. 2 1
      mirai-core/src/commonMain/kotlin/network/notice/priv/FriendNoticeProcessor.kt
  18. 1 1
      mirai-core/src/commonMain/kotlin/network/notice/priv/OtherClientNoticeProcessor.kt
  19. 13 8
      mirai-core/src/commonMain/kotlin/network/notice/priv/PrivateMessageNoticeProcessor.kt
  20. 2 2
      mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Cmd0x857.kt
  21. 9 205
      mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt

+ 4 - 2
buildSrc/src/main/kotlin/ProjectConfigure.kt

@@ -12,9 +12,9 @@
 import org.gradle.api.JavaVersion
 import org.gradle.api.Project
 import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.bundling.Jar
 import org.gradle.api.tasks.compile.JavaCompile
 import org.gradle.api.tasks.testing.Test
-import org.gradle.api.tasks.bundling.Jar
 import org.gradle.kotlin.dsl.*
 import org.jetbrains.kotlin.gradle.dsl.*
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
@@ -144,7 +144,9 @@ val experimentalAnnotations = arrayOf(
     "net.mamoe.mirai.message.data.ExperimentalMessageKey",
     "net.mamoe.mirai.console.ConsoleFrontEndImplementation",
     "net.mamoe.mirai.console.util.ConsoleInternalApi",
-    "net.mamoe.mirai.console.util.ConsoleExperimentalApi"
+    "net.mamoe.mirai.console.util.ConsoleExperimentalApi",
+
+    "kotlinx.io.core.internal.DangerousInternalIoApi",
 )
 
 fun Project.configureKotlinExperimentalUsages() {

+ 4 - 1
mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt

@@ -109,4 +109,7 @@ public fun String.truncated(length: Int, truncated: String = "..."): String {
 public inline fun <T> T.context(block: T.() -> Unit) {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return block()
-}
+}
+
+public fun assertUnreachable(hint: String? = null): Nothing =
+    error("This clause should not be reached. " + hint.orEmpty())

+ 16 - 6
mirai-core/src/commonMain/kotlin/QQAndroidBot.kt

@@ -37,8 +37,15 @@ import net.mamoe.mirai.internal.network.handler.state.StateObserver
 import net.mamoe.mirai.internal.network.handler.state.safe
 import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException
 import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory
-import net.mamoe.mirai.internal.network.notice.*
+import net.mamoe.mirai.internal.network.notice.UnconsumedNoticesAlerter
+import net.mamoe.mirai.internal.network.notice.decoders.GroupNotificationDecoder
 import net.mamoe.mirai.internal.network.notice.decoders.MsgInfoDecoder
+import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor
+import net.mamoe.mirai.internal.network.notice.group.GroupOrMemberListNoticeProcessor
+import net.mamoe.mirai.internal.network.notice.group.GroupRecallProcessor
+import net.mamoe.mirai.internal.network.notice.priv.FriendNoticeProcessor
+import net.mamoe.mirai.internal.network.notice.priv.OtherClientNoticeProcessor
+import net.mamoe.mirai.internal.network.notice.priv.PrivateMessageNoticeProcessor
 import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
 import net.mamoe.mirai.internal.utils.subLogger
 import net.mamoe.mirai.utils.BotConfiguration
@@ -156,13 +163,16 @@ internal open class QQAndroidBot constructor(
         set(
             NoticeProcessorPipeline,
             NoticeProcessorPipelineImpl.create(
-                MsgInfoDecoder(pipelineLogger),
-                FriendNoticeProcessor(pipelineLogger),
-                GroupListNoticeProcessor(pipelineLogger),
-                GroupMessageProcessor(),
+                MsgInfoDecoder(pipelineLogger.subLogger("MsgInfoDecoder")),
+                GroupNotificationDecoder(),
+
+                FriendNoticeProcessor(pipelineLogger.subLogger("FriendNoticeProcessor")),
+                GroupOrMemberListNoticeProcessor(pipelineLogger.subLogger("GroupOrMemberListNoticeProcessor")),
+                GroupMessageProcessor(pipelineLogger.subLogger("GroupMessageProcessor")),
                 PrivateMessageNoticeProcessor(),
                 OtherClientNoticeProcessor(),
-                UnconsumedNoticesAlerter(pipelineLogger),
+                UnconsumedNoticesAlerter(pipelineLogger.subLogger("UnconsumedNoticesAlerter")),
+                GroupRecallProcessor()
             )
         )
 

+ 1 - 1
mirai-core/src/commonMain/kotlin/contact/AbstractMember.kt

@@ -16,7 +16,7 @@ import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
 import net.mamoe.mirai.utils.cast
 import kotlin.coroutines.CoroutineContext
 
-internal abstract class AbstractMember(
+internal sealed class AbstractMember(
     final override val group: GroupImpl,
     parentCoroutineContext: CoroutineContext,
     memberInfo: MemberInfo,

+ 1 - 1
mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt

@@ -57,7 +57,7 @@ internal val User.correspondingMessageSourceKind
         else -> error("Unknown user: ${this::class.qualifiedName}")
     }
 
-internal abstract class AbstractUser(
+internal sealed class AbstractUser(
     bot: QQAndroidBot,
     parentCoroutineContext: CoroutineContext,
     userInfo: UserInfo,

+ 1 - 3
mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt

@@ -14,16 +14,14 @@ import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.async
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.event.nextEventOrNull
-import net.mamoe.mirai.internal.MiraiImpl
 import net.mamoe.mirai.internal.asQQAndroidBot
 import net.mamoe.mirai.internal.getMiraiImpl
 import net.mamoe.mirai.internal.message.*
-import net.mamoe.mirai.internal.message.LightMessageRefiner.refineLight
 import net.mamoe.mirai.internal.network.Packet
 import net.mamoe.mirai.internal.network.QQAndroidClient
 import net.mamoe.mirai.internal.network.components.MessageSvcSyncer
 import net.mamoe.mirai.internal.network.handler.logger
-import net.mamoe.mirai.internal.network.notice.GroupMessageProcessor.SendGroupMessageReceipt
+import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor.SendGroupMessageReceipt
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
 import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
 import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement

+ 6 - 0
mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt

@@ -28,6 +28,10 @@ import net.mamoe.mirai.internal.QQAndroidBot
 import net.mamoe.mirai.internal.asQQAndroidBot
 import net.mamoe.mirai.internal.contact.GroupImpl
 import net.mamoe.mirai.internal.contact.OnlineAnnouncementImpl
+import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.deleteGroupAnnouncement
+import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.getGroupAnnouncement
+import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.getRawGroupAnnouncements
+import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.sendGroupAnnouncement
 import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.toAnnouncement
 import net.mamoe.mirai.internal.contact.announcement.AnnouncementProtocol.toGroupAnnouncement
 import net.mamoe.mirai.internal.network.highway.ChannelKind
@@ -37,6 +41,8 @@ import net.mamoe.mirai.internal.network.psKey
 import net.mamoe.mirai.internal.network.sKey
 import net.mamoe.mirai.internal.utils.io.writeResource
 import net.mamoe.mirai.utils.*
+import net.mamoe.mirai.utils.Either.Companion.onLeft
+import net.mamoe.mirai.utils.Either.Companion.rightOrNull
 import java.util.stream.Stream
 
 internal class AnnouncementsImpl(

+ 1 - 1
mirai-core/src/commonMain/kotlin/message/outgoingSourceImpl.kt

@@ -20,7 +20,7 @@ import net.mamoe.mirai.Bot
 import net.mamoe.mirai.Mirai
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.event.asyncFromEventOrNull
-import net.mamoe.mirai.internal.network.notice.GroupMessageProcessor.SendGroupMessageReceipt
+import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor.SendGroupMessageReceipt
 import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
 import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg

+ 18 - 13
mirai-core/src/commonMain/kotlin/network/components/NoticeProcessorPipeline.kt

@@ -15,6 +15,7 @@ import net.mamoe.mirai.internal.network.Packet
 import net.mamoe.mirai.internal.network.ParseErrorPacket
 import net.mamoe.mirai.internal.network.component.ComponentKey
 import net.mamoe.mirai.internal.network.component.ComponentStorage
+import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
 import net.mamoe.mirai.internal.network.notice.decoders.MsgType0x2DC
 import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
 import net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushStatus
@@ -32,7 +33,6 @@ import net.mamoe.mirai.utils.toDebugString
 import net.mamoe.mirai.utils.uncheckedCast
 import java.util.*
 import java.util.concurrent.ConcurrentLinkedQueue
-import java.util.concurrent.CopyOnWriteArrayList
 import kotlin.reflect.KClass
 
 internal typealias ProcessResult = Collection<Packet>
@@ -98,8 +98,8 @@ internal interface PipelineContext {
     val collected: MutableProcessResult
 
     // DSL to simplify some expressions
-    operator fun MutableProcessResult.plusAssign(packet: Packet) {
-        collect(packet)
+    operator fun MutableProcessResult.plusAssign(packet: Packet?) {
+        if (packet != null) collect(packet)
     }
 
 
@@ -114,11 +114,11 @@ internal interface PipelineContext {
     fun collect(packets: Iterable<Packet>)
 
     /**
-     * Fire the [data] into the processor pipeline.
+     * Fire the [data] into the processor pipeline, and collect the results to current [collected].
      *
-     * @return result collected from processors. This would also have been collected to this context (where you call [fire]).
+     * @return result collected from processors. This would also have been collected to this context (where you call [processAlso]).
      */
-    suspend fun fire(data: ProtocolStruct): ProcessResult
+    suspend fun processAlso(data: ProtocolStruct): ProcessResult
 
     companion object {
         val KEY_FROM_SYNC = TypeKey<Boolean>("fromSync")
@@ -129,7 +129,10 @@ internal interface PipelineContext {
 internal inline val PipelineContext.context get() = this
 
 internal open class NoticeProcessorPipelineImpl private constructor() : NoticeProcessorPipeline {
-    private val processors = CopyOnWriteArrayList<NoticeProcessor>()
+    /**
+     * Must be ordered
+     */
+    private val processors = ConcurrentLinkedQueue<NoticeProcessor>()
 
     override fun registerProcessor(processor: NoticeProcessor) {
         processors.add(processor)
@@ -141,7 +144,7 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
     ) : PipelineContext {
         private val consumers: Stack<NoticeProcessor> = Stack()
 
-        override val isConsumed: Boolean = consumers.isNotEmpty()
+        override val isConsumed: Boolean get() = consumers.isNotEmpty()
         override fun NoticeProcessor.markAsConsumed() {
             consumers.push(this)
         }
@@ -162,7 +165,7 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
             this.collected.data.addAll(packets)
         }
 
-        override suspend fun fire(data: ProtocolStruct): ProcessResult {
+        override suspend fun processAlso(data: ProtocolStruct): ProcessResult {
             return process(bot, data, attributes)
         }
     }
@@ -193,7 +196,6 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
 
 
     companion object {
-        fun createEmpty(): NoticeProcessorPipelineImpl = NoticeProcessorPipelineImpl()
         fun create(vararg processors: NoticeProcessor): NoticeProcessorPipelineImpl =
             NoticeProcessorPipelineImpl().apply {
                 for (processor in processors) {
@@ -214,9 +216,9 @@ internal interface NoticeProcessor {
     suspend fun process(context: PipelineContext, data: Any?)
 }
 
-internal abstract class AnyNoticeProcessor : SimpleNoticeProcessor<Any>(type())
+internal abstract class AnyNoticeProcessor : SimpleNoticeProcessor<ProtocolStruct>(type())
 
-internal abstract class SimpleNoticeProcessor<T : Any>(
+internal abstract class SimpleNoticeProcessor<in T : ProtocolStruct>(
     private val type: KClass<T>,
 ) : NoticeProcessor {
 
@@ -239,7 +241,7 @@ internal abstract class MsgCommonMsgProcessor : SimpleNoticeProcessor<MsgComm.Ms
 }
 
 internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
-    final override suspend fun PipelineContext.processImpl(data: Any) {
+    final override suspend fun PipelineContext.processImpl(data: ProtocolStruct) {
         when (data) {
             is PbMsgInfo -> processImpl(data)
             is MsgOnlinePush.PbPushMsg -> processImpl(data)
@@ -248,6 +250,7 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
             is MsgType0x2DC -> processImpl(data)
             is Structmsg.StructMsg -> processImpl(data)
             is RequestPushStatus -> processImpl(data)
+            is DecodedNotifyMsgBody -> processImpl(data)
         }
     }
 
@@ -258,4 +261,6 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
     protected open suspend fun PipelineContext.processImpl(data: MsgComm.Msg) {}
     protected open suspend fun PipelineContext.processImpl(data: Structmsg.StructMsg) {}
     protected open suspend fun PipelineContext.processImpl(data: RequestPushStatus) {}
+
+    protected open suspend fun PipelineContext.processImpl(data: DecodedNotifyMsgBody) {}
 }

+ 1 - 1
mirai-core/src/commonMain/kotlin/network/notice/NewContactSupport.kt

@@ -27,7 +27,7 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
 import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
 import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
 
-internal interface NewContactSupport {
+internal interface NewContactSupport { // can be a marker interface when context receivers are available.
 
     fun MsgComm.Msg.getNewMemberInfo(): MemberInfoImpl {
         return MemberInfoImpl(

+ 34 - 0
mirai-core/src/commonMain/kotlin/network/notice/decoders/GroupNotificationDecoder.kt

@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ * https://github.com/mamoe/mirai/blob/dev/LICENSE
+ */
+
+package net.mamoe.mirai.internal.network.notice.decoders
+
+import net.mamoe.mirai.internal.contact.GroupImpl
+import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
+import net.mamoe.mirai.internal.network.components.PipelineContext
+import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
+import net.mamoe.mirai.internal.utils.io.ProtocolStruct
+import net.mamoe.mirai.internal.utils.io.serialization.loadAs
+
+internal class GroupNotificationDecoder : MixedNoticeProcessor() {
+    override suspend fun PipelineContext.processImpl(data: MsgType0x2DC) {
+        when (data.kind) {
+            0x10 -> {
+                val proto = data.buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), offset = 1)
+                processAlso(DecodedNotifyMsgBody(data.kind, data.group, proto))
+            }
+        }
+    }
+}
+
+internal data class DecodedNotifyMsgBody(
+    override val kind: Int,
+    override val group: GroupImpl,
+    override val buf: TroopTips0x857.NotifyMsgBody,
+) : BaseMsgType0x2DC<TroopTips0x857.NotifyMsgBody>, ProtocolStruct

+ 36 - 7
mirai-core/src/commonMain/kotlin/network/notice/decoders/MsgInfoDecoder.kt

@@ -46,7 +46,7 @@ internal class MsgInfoDecoder(
         if (!bot.syncController.syncOnlinePush(data)) return
         when (data.shMsgType.toUShort().toInt()) {
             // 528
-            0x210 -> fire(data.vMsg.loadAs(MsgType0x210.serializer()))
+            0x210 -> processAlso(data.vMsg.loadAs(MsgType0x210.serializer()))
 
             // 732
             0x2dc -> {
@@ -57,7 +57,7 @@ internal class MsgInfoDecoder(
                     val kind = readByte().toInt()
                     discardExact(1)
 
-                    fire(MsgType0x2DC(kind, group, this.readBytes()))
+                    processAlso(MsgType0x2DC(kind, group, this.readBytes()))
                 }
             }
             else -> {
@@ -67,8 +67,37 @@ internal class MsgInfoDecoder(
     }
 }
 
-internal class MsgType0x2DC(
-    val kind: Int, // inner kind, read from vMsg
-    val group: GroupImpl,
-    val buf: ByteArray,
-) : ProtocolStruct
+internal interface BaseMsgType0x2DC<V> {
+    val kind: Int
+    val group: GroupImpl
+    val buf: V
+
+    fun Long.findMember() = group[this]
+    fun String.findMember() = this.toLongOrNull()?.let { group[it] }
+}
+
+internal data class MsgType0x2DC(
+    override val kind: Int, // inner kind, read from vMsg
+    override val group: GroupImpl,
+    override val buf: ByteArray,
+) : ProtocolStruct, BaseMsgType0x2DC<ByteArray> {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as MsgType0x2DC
+
+        if (kind != other.kind) return false
+        if (group != other.group) return false
+        if (!buf.contentEquals(other.buf)) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = kind
+        result = 31 * result + group.hashCode()
+        result = 31 * result + buf.contentHashCode()
+        return result
+    }
+}

+ 7 - 5
mirai-core/src/commonMain/kotlin/network/notice/GroupMessageProcessor.kt → mirai-core/src/commonMain/kotlin/network/notice/group/GroupMessageProcessor.kt

@@ -7,7 +7,7 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package net.mamoe.mirai.internal.network.notice
+package net.mamoe.mirai.internal.network.notice.group
 
 import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.event.AbstractEvent
@@ -26,8 +26,8 @@ import net.mamoe.mirai.internal.network.Packet
 import net.mamoe.mirai.internal.network.components.PipelineContext
 import net.mamoe.mirai.internal.network.components.SimpleNoticeProcessor
 import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
-import net.mamoe.mirai.internal.network.handler.logger
-import net.mamoe.mirai.internal.network.notice.GroupMessageProcessor.MemberNick.Companion.generateMemberNickFromMember
+import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor.MemberNick.Companion.generateMemberNickFromMember
+import net.mamoe.mirai.internal.network.notice.priv.PrivateMessageNoticeProcessor
 import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
@@ -39,7 +39,9 @@ import net.mamoe.mirai.utils.*
 /**
  * Handles [GroupMessageEvent]. For private message events, see [PrivateMessageNoticeProcessor]
  */
-internal class GroupMessageProcessor : SimpleNoticeProcessor<MsgOnlinePush.PbPushMsg>(type()) {
+internal class GroupMessageProcessor(
+    private val logger: MiraiLogger,
+) : SimpleNoticeProcessor<MsgOnlinePush.PbPushMsg>(type()) {
     internal data class SendGroupMessageReceipt(
         val messageRandom: Int,
         val sequenceId: Int,
@@ -113,7 +115,7 @@ internal class GroupMessageProcessor : SimpleNoticeProcessor<MsgOnlinePush.PbPus
             nameCard = sender.generateMemberNickFromMember()
         } else { // normal member chat
             sender = group[msgHead.fromUin] ?: kotlin.run {
-                bot.network.logger.warning { "Failed to find member ${msgHead.fromUin} in group ${group.id}" }
+                logger.warning { "Failed to find member ${msgHead.fromUin} in group ${group.id}" }
                 return
             }
             nameCard = findSenderName(extraInfo, msgHead.groupInfo) ?: sender.generateMemberNickFromMember()

+ 213 - 0
mirai-core/src/commonMain/kotlin/network/notice/group/GroupNotificationProcessor.kt

@@ -0,0 +1,213 @@
+/*
+ * 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.
+ *
+ * https://github.com/mamoe/mirai/blob/dev/LICENSE
+ */
+
+package net.mamoe.mirai.internal.network.notice.group
+
+import kotlinx.io.core.readUInt
+import kotlinx.io.core.readUShort
+import net.mamoe.mirai.contact.NormalMember
+import net.mamoe.mirai.data.GroupHonorType
+import net.mamoe.mirai.event.events.*
+import net.mamoe.mirai.internal.QQAndroidBot
+import net.mamoe.mirai.internal.contact.GroupImpl
+import net.mamoe.mirai.internal.contact.checkIsMemberImpl
+import net.mamoe.mirai.internal.network.Packet
+import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
+import net.mamoe.mirai.internal.network.components.PipelineContext
+import net.mamoe.mirai.internal.network.handler.logger
+import net.mamoe.mirai.internal.network.notice.NewContactSupport
+import net.mamoe.mirai.internal.network.notice.decoders.MsgType0x2DC
+import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
+import net.mamoe.mirai.internal.utils._miraiContentToString
+import net.mamoe.mirai.internal.utils.io.serialization.loadAs
+import net.mamoe.mirai.utils.context
+import net.mamoe.mirai.utils.currentTimeSeconds
+import net.mamoe.mirai.utils.debug
+import net.mamoe.mirai.utils.read
+
+internal class GroupNotificationProcessor : MixedNoticeProcessor(), NewContactSupport {
+    override suspend fun PipelineContext.processImpl(data: MsgType0x2DC) {
+        when (data.kind) {
+            0x0C -> processMute(data)
+            0x0E -> processAllowAnonymousChat(data)
+            0x10 -> processAllowConfessTask(data)
+            0x14 -> processGrayTip(data)
+        }
+    }
+
+    /**
+     * @see MemberMuteEvent
+     * @see MemberUnmuteEvent
+     * @see GroupMuteAllEvent
+     * @see BotMuteEvent
+     * @see BotUnmuteEvent
+     */
+    private fun PipelineContext.processMute(
+        data: MsgType0x2DC,
+    ) = data.context {
+        fun handleMuteMemberPacket(
+            bot: QQAndroidBot,
+            group: GroupImpl,
+            operator: NormalMember,
+            target: Long,
+            timeSeconds: Int,
+        ): Packet? {
+            if (target == 0L) {
+                val new = timeSeconds != 0
+                if (group.settings.isMuteAllField == new) {
+                    return null
+                }
+                group.settings.isMuteAllField = new
+                return GroupMuteAllEvent(!new, new, group, operator)
+            }
+
+            if (target == bot.id) {
+                return when {
+                    group.botMuteRemaining == timeSeconds -> null
+                    timeSeconds == 0 || timeSeconds == 0xFFFF_FFFF.toInt() -> {
+                        group.botAsMember.checkIsMemberImpl()._muteTimestamp = 0
+                        BotUnmuteEvent(operator)
+                    }
+                    else -> {
+                        group.botAsMember.checkIsMemberImpl()._muteTimestamp =
+                            currentTimeSeconds().toInt() + timeSeconds
+                        BotMuteEvent(timeSeconds, operator)
+                    }
+                }
+            }
+
+            val member = group[target] ?: return null
+            member.checkIsMemberImpl()
+
+            if (member.muteTimeRemaining == timeSeconds) return null
+
+            member._muteTimestamp = currentTimeSeconds().toInt() + timeSeconds
+            return if (timeSeconds == 0) MemberUnmuteEvent(member, operator)
+            else MemberMuteEvent(member, timeSeconds, operator)
+        }
+
+        markAsConsumed()
+
+        buf.read {
+            val operatorUin = readUInt().toLong()
+            if (operatorUin == bot.id) return
+            val operator = group[operatorUin] ?: return
+            readUInt().toLong() // time
+            val length = readUShort().toInt()
+            repeat(length) {
+                val target = readUInt().toLong()
+                val timeSeconds = readUInt()
+                collected += handleMuteMemberPacket(bot, group, operator, target, timeSeconds.toInt())
+            }
+        }
+    }
+
+    /**
+     * @see GroupAllowAnonymousChatEvent
+     */
+    private fun PipelineContext.processAllowAnonymousChat(
+        data: MsgType0x2DC,
+    ) = data.context {
+        markAsConsumed()
+        buf.read {
+            val operator = group[readUInt().toLong()] ?: return
+            val new = readInt() == 0
+            if (group.settings.isAnonymousChatEnabledField == new) return
+
+            group.settings.isAnonymousChatEnabledField = new
+            collect(GroupAllowAnonymousChatEvent(!new, new, group, operator))
+        }
+    }
+
+    /**
+     * @see GroupAllowConfessTalkEvent
+     */
+    private fun PipelineContext.processAllowConfessTask(
+        data: MsgType0x2DC,
+    ) = data.context {
+        val proto = data.buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), offset = 1)
+        markAsConsumed()
+        when (proto.optEnumType) {
+            1 -> {
+                val tipsInfo = proto.optMsgGraytips ?: return
+
+                val message = tipsInfo.optBytesContent.decodeToString()
+                // 机器人信息
+                when (tipsInfo.robotGroupOpt) {
+                    // others
+                    0 -> {
+                        if (message.endsWith("群聊坦白说")) {
+                            val new = when (message) {
+                                "管理员已关闭群聊坦白说" -> false
+                                "管理员已开启群聊坦白说" -> true
+                                else -> {
+                                    bot.network.logger.debug { "Unknown server confess talk messages $message" }
+                                    return
+                                }
+                            }
+                            collect(GroupAllowConfessTalkEvent(new, !new, group, false))
+                        }
+                    }
+                }
+            }
+            else -> markNotConsumed()
+        }
+    }
+
+    /**
+     * @see NudgeEvent
+     * @see MemberHonorChangeEvent
+     * @see GroupTalkativeChangeEvent
+     */
+    private fun PipelineContext.processGrayTip(
+        data: MsgType0x2DC,
+    ) = data.context {
+        val grayTip = buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), 1).optGeneralGrayTip
+        markAsConsumed()
+        when (grayTip?.templId) {
+            // 戳一戳
+            10043L, 1133L, 1132L, 1134L, 1135L, 1136L -> {
+                //预置数据,服务器将不会提供己方已知消息
+                val action = grayTip.msgTemplParam["action_str"].orEmpty()
+                val from = grayTip.msgTemplParam["uin_str1"]?.findMember() ?: group.botAsMember
+                val target = grayTip.msgTemplParam["uin_str2"]?.findMember() ?: group.botAsMember
+                val suffix = grayTip.msgTemplParam["suffix_str"].orEmpty()
+
+                collected += NudgeEvent(
+                    from = if (from.id == bot.id) bot else from,
+                    target = if (target.id == bot.id) bot else target,
+                    action = action,
+                    suffix = suffix,
+                    subject = group,
+                )
+            }
+            // 龙王
+            10093L, 1053L, 1054L -> {
+                val now: NormalMember = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
+                val previous: NormalMember? = grayTip.msgTemplParam["uin_last"]?.findMember()
+
+                if (previous == null) {
+                    collect(MemberHonorChangeEvent.Achieve(now, GroupHonorType.TALKATIVE))
+                } else {
+                    collect(GroupTalkativeChangeEvent(group, now, previous))
+                    collect(MemberHonorChangeEvent.Lose(previous, GroupHonorType.TALKATIVE))
+                    collect(MemberHonorChangeEvent.Achieve(now, GroupHonorType.TALKATIVE))
+                }
+            }
+            else -> {
+                markNotConsumed()
+                bot.network.logger.debug {
+                    "Unknown Transformers528 0x14 template\ntemplId=${grayTip?.templId}\nPermList=${grayTip?.msgTemplParam?._miraiContentToString()}"
+                }
+            }
+        }
+    }
+}
+
+internal operator fun List<TroopTips0x857.TemplParam>.get(name: String) = this.findLast { it.name == name }?.value

+ 12 - 14
mirai-core/src/commonMain/kotlin/network/notice/GroupListNoticeProcessor.kt → mirai-core/src/commonMain/kotlin/network/notice/group/GroupOrMemberListNoticeProcessor.kt

@@ -7,7 +7,7 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package net.mamoe.mirai.internal.network.notice
+package net.mamoe.mirai.internal.network.notice.group
 
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.cancel
@@ -25,16 +25,19 @@ import net.mamoe.mirai.internal.message.contextualBugReportException
 import net.mamoe.mirai.internal.network.components.ContactUpdater
 import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
 import net.mamoe.mirai.internal.network.components.PipelineContext
-import net.mamoe.mirai.internal.network.notice.decoders.MsgType0x2DC
+import net.mamoe.mirai.internal.network.notice.NewContactSupport
+import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
 import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
-import net.mamoe.mirai.internal.network.protocol.data.proto.*
+import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
+import net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans
+import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
+import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x44
 import net.mamoe.mirai.internal.utils._miraiContentToString
 import net.mamoe.mirai.internal.utils.io.serialization.loadAs
 import net.mamoe.mirai.internal.utils.parseToMessageDataList
 import net.mamoe.mirai.internal.utils.toMemberInfo
 import net.mamoe.mirai.utils.MiraiLogger
 import net.mamoe.mirai.utils.context
-import net.mamoe.mirai.utils.debug
 import net.mamoe.mirai.utils.read
 
 
@@ -54,7 +57,7 @@ import net.mamoe.mirai.utils.read
  * @see BotInvitedJoinGroupRequestEvent
  * @see MemberJoinRequestEvent
  */
-internal class GroupListNoticeProcessor(
+internal class GroupOrMemberListNoticeProcessor(
     private val logger: MiraiLogger,
 ) : MixedNoticeProcessor(), NewContactSupport {
 
@@ -79,14 +82,14 @@ internal class GroupListNoticeProcessor(
      * @see MemberJoinEvent.Invite
      * @see MemberLeaveEvent.Quit
      */
-    override suspend fun PipelineContext.processImpl(data: MsgType0x2DC) = data.context {
-        if (data.kind != 0x10) return
-        val proto = data.buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), offset = 1)
+    override suspend fun PipelineContext.processImpl(data: DecodedNotifyMsgBody) = data.context {
+        val proto = data.buf
         if (proto.optEnumType != 1) return
         val tipsInfo = proto.optMsgGraytips ?: return
 
         val message = tipsInfo.optBytesContent.decodeToString()
         // 机器人信息
+        markAsConsumed()
         when (tipsInfo.robotGroupOpt) {
             // 添加
             1 -> {
@@ -107,13 +110,8 @@ internal class GroupListNoticeProcessor(
                     collect(MemberLeaveEvent.Quit(member))
                 }
             }
-
-            else -> {
-                logger.debug { "Unknown robotGroupOpt ${tipsInfo.robotGroupOpt}, message=$message" }
-            }
+            else -> markNotConsumed()
         }
-
-        return markAsConsumed()
     }
 
     /**

+ 45 - 0
mirai-core/src/commonMain/kotlin/network/notice/group/GroupRecallProcessor.kt

@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ * https://github.com/mamoe/mirai/blob/dev/LICENSE
+ */
+
+package net.mamoe.mirai.internal.network.notice.group
+
+import net.mamoe.mirai.event.events.MessageRecallEvent
+import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
+import net.mamoe.mirai.internal.network.components.PipelineContext
+import net.mamoe.mirai.internal.network.notice.decoders.MsgType0x2DC
+import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
+import net.mamoe.mirai.internal.utils.io.serialization.loadAs
+import net.mamoe.mirai.utils.mapToIntArray
+
+internal class GroupRecallProcessor : MixedNoticeProcessor() {
+    override suspend fun PipelineContext.processImpl(data: MsgType0x2DC) {
+        val (_, group, buf) = data
+
+        val proto = buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), 1)
+
+        val recallReminder = proto.optMsgRecall ?: return
+        val operator = group[recallReminder.uin] ?: return
+        markAsConsumed()
+        for (firstPkg in recallReminder.recalledMsgList) {
+            if (firstPkg.authorUin == bot.id && operator.id == bot.id) continue // already broadcast
+            val author = group[firstPkg.authorUin] ?: continue
+
+            collected += MessageRecallEvent.GroupRecall(
+                bot = bot,
+                authorId = firstPkg.authorUin,
+                messageIds = recallReminder.recalledMsgList.mapToIntArray { it.seq },
+                messageInternalIds = recallReminder.recalledMsgList.mapToIntArray { it.msgRandom },
+                messageTime = firstPkg.time,
+                operator = operator,
+                group = group,
+                author = author,
+            )
+        }
+    }
+}

+ 2 - 1
mirai-core/src/commonMain/kotlin/network/notice/FriendNoticeProcessor.kt → mirai-core/src/commonMain/kotlin/network/notice/priv/FriendNoticeProcessor.kt

@@ -7,7 +7,7 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package net.mamoe.mirai.internal.network.notice
+package net.mamoe.mirai.internal.network.notice.priv
 
 import kotlinx.io.core.discardExact
 import kotlinx.io.core.readUByte
@@ -19,6 +19,7 @@ import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl
 import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
 import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
 import net.mamoe.mirai.internal.network.components.PipelineContext
+import net.mamoe.mirai.internal.network.notice.NewContactSupport
 import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
 import net.mamoe.mirai.internal.network.protocol.data.proto.FrdSysMsg
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm

+ 1 - 1
mirai-core/src/commonMain/kotlin/network/notice/OtherClientNoticeProcessor.kt → mirai-core/src/commonMain/kotlin/network/notice/priv/OtherClientNoticeProcessor.kt

@@ -7,7 +7,7 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package net.mamoe.mirai.internal.network.notice
+package net.mamoe.mirai.internal.network.notice.priv
 
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.cancel

+ 13 - 8
mirai-core/src/commonMain/kotlin/network/notice/PrivateMessageNoticeProcessor.kt → mirai-core/src/commonMain/kotlin/network/notice/priv/PrivateMessageNoticeProcessor.kt

@@ -7,9 +7,8 @@
  *  https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
-package net.mamoe.mirai.internal.network.notice
+package net.mamoe.mirai.internal.network.notice.priv
 
-import net.mamoe.mirai.contact.User
 import net.mamoe.mirai.event.events.*
 import net.mamoe.mirai.internal.contact.*
 import net.mamoe.mirai.internal.getGroupByUin
@@ -18,7 +17,9 @@ import net.mamoe.mirai.internal.network.components.PipelineContext
 import net.mamoe.mirai.internal.network.components.PipelineContext.Companion.fromSync
 import net.mamoe.mirai.internal.network.components.SimpleNoticeProcessor
 import net.mamoe.mirai.internal.network.components.SsoProcessor
+import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor
 import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
+import net.mamoe.mirai.utils.assertUnreachable
 import net.mamoe.mirai.utils.context
 
 /**
@@ -47,7 +48,12 @@ internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg
             166, 167, // 单向好友
             208, // friend ptt, maybe also support stranger
             -> {
-                handlePrivateMessage(data, bot.getFriend(senderUin) ?: bot.getStranger(senderUin) ?: return)
+                handlePrivateMessage(
+                    data,
+                    bot.getFriend(senderUin)?.impl()
+                        ?: bot.getStranger(senderUin)?.impl()
+                        ?: return
+                )
             }
 
             141, // group temp
@@ -63,9 +69,8 @@ internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg
 
     private suspend fun PipelineContext.handlePrivateMessage(
         data: MsgComm.Msg,
-        user: User,
+        user: AbstractUser,
     ) = data.context {
-        user.impl()
         if (!user.messageSeq.updateIfDifferentWith(msgHead.msgSeq)) return
         if (contentHead?.autoReply == 1) return
 
@@ -80,15 +85,15 @@ internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg
                 is FriendImpl -> FriendMessageSyncEvent(user, chain, time)
                 is StrangerImpl -> StrangerMessageSyncEvent(user, chain, time)
                 is NormalMemberImpl -> GroupTempMessageSyncEvent(user, chain, time)
-                else -> null
+                is AnonymousMemberImpl -> assertUnreachable()
             }
         } else {
             when (user) {
                 is FriendImpl -> FriendMessageEvent(user, chain, time)
                 is StrangerImpl -> StrangerMessageEvent(user, chain, time)
                 is NormalMemberImpl -> GroupTempMessageEvent(user, chain, time)
-                else -> null
+                is AnonymousMemberImpl -> assertUnreachable()
             }
-        } ?: error("unreachable")
+        }
     }
 }

+ 2 - 2
mirai-core/src/commonMain/kotlin/network/protocol/data/proto/Cmd0x857.kt

@@ -320,8 +320,8 @@ internal class TroopTips0x857 : ProtoBuf {
 
     @Serializable
     internal class TemplParam(
-        @ProtoNumber(1) @JvmField val name: ByteArray = EMPTY_BYTE_ARRAY,
-        @ProtoNumber(2) @JvmField val value: ByteArray = EMPTY_BYTE_ARRAY,
+        @ProtoNumber(1) @JvmField val name: String = "",
+        @ProtoNumber(2) @JvmField val value: String = "",
     ) : ProtoBuf
 
     @Serializable

+ 9 - 205
mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt

@@ -10,16 +10,13 @@
 package net.mamoe.mirai.internal.network.protocol.packet.chat.receive
 
 import kotlinx.io.core.ByteReadPacket
-import kotlinx.io.core.discardExact
-import kotlinx.io.core.readUInt
-import kotlinx.io.core.readUShort
 import kotlinx.serialization.Serializable
 import kotlinx.serialization.protobuf.ProtoNumber
-import net.mamoe.mirai.contact.Member
-import net.mamoe.mirai.contact.NormalMember
 import net.mamoe.mirai.contact.User
-import net.mamoe.mirai.data.GroupHonorType
-import net.mamoe.mirai.event.events.*
+import net.mamoe.mirai.event.events.GroupNameChangeEvent
+import net.mamoe.mirai.event.events.MemberCardChangeEvent
+import net.mamoe.mirai.event.events.MessageRecallEvent
+import net.mamoe.mirai.event.events.NudgeEvent
 import net.mamoe.mirai.internal.QQAndroidBot
 import net.mamoe.mirai.internal.contact.GroupImpl
 import net.mamoe.mirai.internal.contact.checkIsGroupImpl
@@ -33,20 +30,16 @@ import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
 import net.mamoe.mirai.internal.network.protocol.data.jce.OnlinePushPack
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x122
 import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x27.SubMsgType0x27.*
-import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
 import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory
 import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
 import net.mamoe.mirai.internal.network.protocol.packet.buildResponseUniPacket
 import net.mamoe.mirai.internal.utils._miraiContentToString
 import net.mamoe.mirai.internal.utils.io.ProtoBuf
 import net.mamoe.mirai.internal.utils.io.serialization.loadAs
-import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
 import net.mamoe.mirai.internal.utils.io.serialization.readUniPacket
 import net.mamoe.mirai.internal.utils.io.serialization.writeJceRequestPacket
-import net.mamoe.mirai.utils.currentTimeSeconds
 import net.mamoe.mirai.utils.debug
 import net.mamoe.mirai.utils.encodeToString
-import net.mamoe.mirai.utils.mapToIntArray
 
 
 //0C 01 B1 89 BE 09 5E 3D 72 A6 00 01 73 68 FC 06 00 00 00 3C
@@ -100,189 +93,24 @@ internal inline fun lambda732(crossinline block: ByteReadPacket.(GroupImpl, QQAn
     }
 }
 
-private fun handleMuteMemberPacket(
-    bot: QQAndroidBot,
-    group: GroupImpl,
-    operator: NormalMember,
-    target: Long,
-    timeSeconds: Int,
-): Packet? {
-    if (target == 0L) {
-        val new = timeSeconds != 0
-        if (group.settings.isMuteAllField == new) {
-            return null
-        }
-        group.settings.isMuteAllField = new
-        return GroupMuteAllEvent(!new, new, group, operator)
-    }
-
-    if (target == bot.id) {
-        return when {
-            group.botMuteRemaining == timeSeconds -> null
-            timeSeconds == 0 || timeSeconds == 0xFFFF_FFFF.toInt() -> {
-                group.botAsMember.checkIsMemberImpl()._muteTimestamp = 0
-                BotUnmuteEvent(operator)
-            }
-            else -> {
-                group.botAsMember.checkIsMemberImpl()._muteTimestamp =
-                    currentTimeSeconds().toInt() + timeSeconds
-                BotMuteEvent(timeSeconds, operator)
-            }
-        }
-    }
-
-    val member = group[target] ?: return null
-    member.checkIsMemberImpl()
-
-    if (member.muteTimeRemaining == timeSeconds) {
-        return null
-    }
-
-    member._muteTimestamp = currentTimeSeconds().toInt() + timeSeconds
-    return if (timeSeconds == 0) MemberUnmuteEvent(member, operator)
-    else MemberMuteEvent(member, timeSeconds, operator)
-}
-
 internal object Transformers732 : Map<Int, Lambda732> by mapOf(
     // mute
     0x0c to lambda732 { group: GroupImpl, bot: QQAndroidBot ->
-        val operatorUin = readUInt().toLong()
-        if (operatorUin == bot.id) {
-            return@lambda732 emptySequence()
-        }
-        val operator = group[operatorUin] ?: return@lambda732 emptySequence()
-        readUInt().toLong() // time
-        val length = readUShort().toInt()
-        val packetList: MutableList<Packet> = mutableListOf()
-        repeat(length) {
-            val target = readUInt().toLong()
-            val timeSeconds = readUInt()
-            handleMuteMemberPacket(bot, group, operator, target, timeSeconds.toInt())?.let {
-                packetList.add(it)
-            }
-        }
-        return@lambda732 packetList.asSequence()
+        TODO("removed")
     },
 
     // anonymous
     0x0e to lambda732 { group: GroupImpl, _: QQAndroidBot ->
-        // 匿名
-        val operator = group[readUInt().toLong()] ?: return@lambda732 emptySequence()
-        val new = readInt() == 0
-        if (group.settings.isAnonymousChatEnabledField == new) {
-            return@lambda732 emptySequence()
-        }
-
-        group.settings.isAnonymousChatEnabledField = new
-        return@lambda732 sequenceOf(GroupAllowAnonymousChatEvent(!new, new, group, operator))
+        TODO("removed")
     },
 
     //系统提示
     0x14 to lambda732 { group: GroupImpl, bot: QQAndroidBot ->
-
-        discardExact(1)
-        val grayTip = readProtoBuf(TroopTips0x857.NotifyMsgBody.serializer()).optGeneralGrayTip
-        when (grayTip?.templId) {
-            //戳一戳
-            10043L, 1133L, 1132L, 1134L, 1135L, 1136L -> {
-                //预置数据,服务器将不会提供己方已知消息
-                var action = ""
-                var from: Member = group.botAsMember
-                var target: Member = group.botAsMember
-                var suffix = ""
-                grayTip.msgTemplParam.map {
-                    Pair(it.name.decodeToString(), it.value.decodeToString())
-                }.asSequence().forEach { (key, value) ->
-                    run {
-                        when (key) {
-                            "action_str" -> action = value
-                            "uin_str1" -> from = group[value.toLong()] ?: return@lambda732 emptySequence()
-                            "uin_str2" -> target = group[value.toLong()] ?: return@lambda732 emptySequence()
-                            "suffix_str" -> suffix = value
-                        }
-                    }
-                }
-                return@lambda732 sequenceOf(
-                    NudgeEvent(
-                        from = if (from.id == bot.id) bot else from,
-                        target = if (target.id == bot.id) bot else target,
-                        action = action,
-                        suffix = suffix,
-                        subject = group,
-                    ),
-                )
-            }
-            //龙王
-            10093L, 1053L, 1054L -> {
-                var now: NormalMember = group.botAsMember
-                var previous: NormalMember? = null
-                grayTip.msgTemplParam.asSequence().map {
-                    it.name.decodeToString() to it.value.decodeToString()
-                }.forEach { (key, value) ->
-                    when (key) {
-                        "uin" -> now = group[value.toLong()] ?: return@lambda732 emptySequence()
-                        "uin_last" -> previous = group[value.toLong()] ?: return@lambda732 emptySequence()
-                    }
-                }
-                return@lambda732 previous?.let {
-                    sequenceOf(
-                        GroupTalkativeChangeEvent(group, now, it),
-                        MemberHonorChangeEvent.Lose(it, GroupHonorType.TALKATIVE),
-                        MemberHonorChangeEvent.Achieve(now, GroupHonorType.TALKATIVE),
-                    )
-                } ?: sequenceOf(MemberHonorChangeEvent.Achieve(now, GroupHonorType.TALKATIVE))
-            }
-            else -> {
-                bot.network.logger.debug {
-                    "Unknown Transformers528 0x14 template\ntemplId=${grayTip?.templId}\nPermList=${grayTip?.msgTemplParam?._miraiContentToString()}"
-                }
-                return@lambda732 emptySequence()
-            }
-        }
+        TODO("removed")
     },
     // 传字符串信息
     0x10 to lambda732 { group: GroupImpl, bot: QQAndroidBot ->
-        discardExact(1)
-        readProtoBuf(TroopTips0x857.NotifyMsgBody.serializer()).let { body ->
-            when (body.optEnumType) {
-                1 -> body.optMsgGraytips?.let { tipsInfo ->
-                    val message = tipsInfo.optBytesContent.decodeToString()
-                    //机器人信息
-                    if (tipsInfo.robotGroupOpt != 0) {
-                        TODO("removed")
-                    } else when {
-                        message.endsWith("群聊坦白说") -> {
-                            val new = when (message) {
-                                "管理员已关闭群聊坦白说" -> false
-                                "管理员已开启群聊坦白说" -> true
-                                else -> {
-                                    bot.network.logger.debug { "Unknown server confess talk messages $message" }
-                                    return@lambda732 emptySequence()
-                                }
-                            }
-                            return@lambda732 sequenceOf(
-                                GroupAllowConfessTalkEvent(
-                                    new,
-                                    !new,
-                                    group,
-                                    false,
-                                ),
-                            )
-                        }
-                        else -> {
-                            bot.network.logger.debug { "Unknown server messages $message" }
-                            return@lambda732 emptySequence()
-                        }
-                    }
-                }
-                else -> {
-                    bot.network.logger.debug {
-                        "Unknown Transformers732 0x10 optEnumType\noptEnumType=${body.optEnumType}\ncontent=${body._miraiContentToString()}"
-                    }
-                    return@lambda732 emptySequence()
-                }
-            } ?: return@lambda732 emptySequence()
-        }
+        TODO("removed")
         /*
         val dataBytes = readBytes(26)
 
@@ -352,31 +180,7 @@ internal object Transformers732 : Map<Int, Lambda732> by mapOf(
 
     // recall
     0x11 to lambda732 { group: GroupImpl, bot: QQAndroidBot ->
-        discardExact(1)
-        val proto = readProtoBuf(TroopTips0x857.NotifyMsgBody.serializer())
-
-        val recallReminder = proto.optMsgRecall ?: return@lambda732 emptySequence()
-
-        val operator =
-            if (recallReminder.uin == bot.id) group.botAsMember
-            else group[recallReminder.uin] ?: return@lambda732 emptySequence()
-        val firstPkg = recallReminder.recalledMsgList.firstOrNull() ?: return@lambda732 emptySequence()
-
-        return@lambda732 when {
-            firstPkg.authorUin == bot.id && operator.id == bot.id -> emptySequence()
-            else -> sequenceOf(
-                MessageRecallEvent.GroupRecall(
-                    bot,
-                    firstPkg.authorUin,
-                    recallReminder.recalledMsgList.mapToIntArray { it.seq },
-                    recallReminder.recalledMsgList.mapToIntArray { it.msgRandom },
-                    firstPkg.time,
-                    operator,
-                    group,
-                    group[firstPkg.authorUin] ?: return@lambda732 emptySequence(),
-                ),
-            )
-        }
+        TODO("removed")
     },
 )