mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-02 12:50:16 +08:00
Migrate more transformers to NoticeProcessorPipeline
This commit is contained in:
parent
e097c5ab9d
commit
edf1bc9a2e
@ -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() {
|
||||
|
@ -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())
|
@ -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()
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
}
|
@ -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(
|
||||
|
@ -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
|
@ -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,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()
|
@ -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
|
@ -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()
|
||||
}
|
||||
|
||||
/**
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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")
|
||||
},
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user