mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-07 16:40:43 +08:00
Add UnconsumedNoticesAlerter
and cleanup
Co-authored-by: Karlatemp <karlatemp@vip.qq.com>
This commit is contained in:
parent
56cbe2d8a2
commit
09265190e9
@ -34,10 +34,10 @@ public value class TypeSafeMap(
|
|||||||
map[key] = value
|
map[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <T> remove(key: TypeKey<T>): T? = map.remove(key).uncheckedCast()
|
public fun <T> remove(key: TypeKey<T>): T? = map.remove(key)?.uncheckedCast()
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun buildTypeSafeMap(block: TypeSafeMap.() -> Unit): TypeSafeMap {
|
public inline fun buildTypeSafeMap(block: TypeSafeMap.() -> Unit): TypeSafeMap {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return TypeSafeMap().apply(block)
|
return TypeSafeMap().apply(block)
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ 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.ForceOfflineException
|
||||||
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory
|
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
|
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
|
||||||
|
import net.mamoe.mirai.internal.network.notice.*
|
||||||
|
import net.mamoe.mirai.internal.network.notice.decoders.MsgInfoDecoder
|
||||||
import net.mamoe.mirai.internal.utils.subLogger
|
import net.mamoe.mirai.internal.utils.subLogger
|
||||||
import net.mamoe.mirai.utils.BotConfiguration
|
import net.mamoe.mirai.utils.BotConfiguration
|
||||||
import net.mamoe.mirai.utils.MiraiLogger
|
import net.mamoe.mirai.utils.MiraiLogger
|
||||||
@ -149,7 +151,20 @@ internal open class QQAndroidBot constructor(
|
|||||||
|
|
||||||
// There's no need to interrupt a broadcasting event when network handler closed.
|
// There's no need to interrupt a broadcasting event when network handler closed.
|
||||||
set(EventDispatcher, EventDispatcherImpl(bot.coroutineContext, logger.subLogger("EventDispatcher")))
|
set(EventDispatcher, EventDispatcherImpl(bot.coroutineContext, logger.subLogger("EventDispatcher")))
|
||||||
set(NoticeProcessorPipeline, NoticeProcessorPipelineImpl(networkLogger.subLogger("NoticeProcessorPipeline")))
|
|
||||||
|
val pipelineLogger = networkLogger.subLogger("NoticeProcessor") // shorten name
|
||||||
|
set(
|
||||||
|
NoticeProcessorPipeline,
|
||||||
|
NoticeProcessorPipelineImpl().apply {
|
||||||
|
registerProcessor(MsgInfoDecoder())
|
||||||
|
registerProcessor(FriendNoticeProcessor(pipelineLogger))
|
||||||
|
registerProcessor(GroupListNoticeProcessor(pipelineLogger))
|
||||||
|
registerProcessor(GroupMessageProcessor())
|
||||||
|
registerProcessor(PrivateMessageNoticeProcessor())
|
||||||
|
registerProcessor(OtherClientNoticeProcessor())
|
||||||
|
registerProcessor(UnconsumedNoticesAlerter(pipelineLogger))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
set(SsoProcessorContext, SsoProcessorContextImpl(bot))
|
set(SsoProcessorContext, SsoProcessorContextImpl(bot))
|
||||||
set(SsoProcessor, SsoProcessorImpl(get(SsoProcessorContext)))
|
set(SsoProcessor, SsoProcessorImpl(get(SsoProcessorContext)))
|
||||||
@ -164,34 +179,35 @@ internal open class QQAndroidBot constructor(
|
|||||||
set(ContactUpdater, ContactUpdaterImpl(bot, components, networkLogger.subLogger("ContactUpdater")))
|
set(ContactUpdater, ContactUpdaterImpl(bot, components, networkLogger.subLogger("ContactUpdater")))
|
||||||
set(
|
set(
|
||||||
BdhSessionSyncer,
|
BdhSessionSyncer,
|
||||||
BdhSessionSyncerImpl(configuration, components, networkLogger.subLogger("BotSessionSyncer"))
|
BdhSessionSyncerImpl(configuration, components, networkLogger.subLogger("BotSessionSyncer")),
|
||||||
)
|
)
|
||||||
set(
|
set(
|
||||||
MessageSvcSyncer,
|
MessageSvcSyncer,
|
||||||
MessageSvcSyncerImpl(bot, bot.coroutineContext, networkLogger.subLogger("MessageSvcSyncer"))
|
MessageSvcSyncerImpl(bot, bot.coroutineContext, networkLogger.subLogger("MessageSvcSyncer")),
|
||||||
)
|
)
|
||||||
set(
|
set(
|
||||||
EcdhInitialPublicKeyUpdater,
|
EcdhInitialPublicKeyUpdater,
|
||||||
EcdhInitialPublicKeyUpdaterImpl(bot, networkLogger.subLogger("ECDHInitialPublicKeyUpdater"))
|
EcdhInitialPublicKeyUpdaterImpl(bot, networkLogger.subLogger("ECDHInitialPublicKeyUpdater")),
|
||||||
)
|
)
|
||||||
set(ServerList, ServerListImpl(networkLogger.subLogger("ServerList")))
|
set(ServerList, ServerListImpl(networkLogger.subLogger("ServerList")))
|
||||||
set(PacketLoggingStrategy, PacketLoggingStrategyImpl(bot))
|
set(PacketLoggingStrategy, PacketLoggingStrategyImpl(bot))
|
||||||
set(
|
set(
|
||||||
PacketHandler, PacketHandlerChain(
|
PacketHandler,
|
||||||
|
PacketHandlerChain(
|
||||||
LoggingPacketHandlerAdapter(get(PacketLoggingStrategy), networkLogger),
|
LoggingPacketHandlerAdapter(get(PacketLoggingStrategy), networkLogger),
|
||||||
EventBroadcasterPacketHandler(components),
|
EventBroadcasterPacketHandler(components),
|
||||||
CallPacketFactoryPacketHandler(bot)
|
CallPacketFactoryPacketHandler(bot),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
set(PacketCodec, PacketCodecImpl())
|
set(PacketCodec, PacketCodecImpl())
|
||||||
set(
|
set(
|
||||||
OtherClientUpdater,
|
OtherClientUpdater,
|
||||||
OtherClientUpdaterImpl(bot, components, networkLogger.subLogger("OtherClientUpdater"))
|
OtherClientUpdaterImpl(bot, components, networkLogger.subLogger("OtherClientUpdater")),
|
||||||
)
|
)
|
||||||
set(ConfigPushSyncer, ConfigPushSyncerImpl())
|
set(ConfigPushSyncer, ConfigPushSyncerImpl())
|
||||||
set(
|
set(
|
||||||
AccountSecretsManager,
|
AccountSecretsManager,
|
||||||
configuration.createAccountsSecretsManager(bot.logger.subLogger("AccountSecretsManager"))
|
configuration.createAccountsSecretsManager(bot.logger.subLogger("AccountSecretsManager")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,13 +229,13 @@ internal open class QQAndroidBot constructor(
|
|||||||
val context = NetworkHandlerContextImpl(
|
val context = NetworkHandlerContextImpl(
|
||||||
bot,
|
bot,
|
||||||
networkLogger,
|
networkLogger,
|
||||||
createNetworkLevelComponents()
|
createNetworkLevelComponents(),
|
||||||
)
|
)
|
||||||
NettyNetworkHandlerFactory.create(
|
NettyNetworkHandlerFactory.create(
|
||||||
context,
|
context,
|
||||||
context[ServerList].pollAny().toSocketAddress()
|
context[ServerList].pollAny().toSocketAddress(),
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
) // We can move the factory to configuration but this is not necessary for now.
|
) // We can move the factory to configuration but this is not necessary for now.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ internal class StrangerImpl(
|
|||||||
}
|
}
|
||||||
bot.network.run {
|
bot.network.run {
|
||||||
StrangerList.DelStranger(bot.client, this@StrangerImpl)
|
StrangerList.DelStranger(bot.client, this@StrangerImpl)
|
||||||
.sendAndExpect<StrangerList.DelStranger.Response>().also {
|
.sendAndExpect().also {
|
||||||
check(it.isSuccess) { "delete Stranger failed: ${it.result}" }
|
check(it.isSuccess) { "delete Stranger failed: ${it.result}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,10 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMs
|
|||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
|
import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetMsg
|
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetMsg
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.OnlinePushPbPushTransMsg
|
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.OnlinePushPbPushTransMsg
|
||||||
import net.mamoe.mirai.utils.MiraiLogger
|
import net.mamoe.mirai.utils.TypeKey
|
||||||
import net.mamoe.mirai.utils.TypeSafeMap
|
import net.mamoe.mirai.utils.TypeSafeMap
|
||||||
import net.mamoe.mirai.utils.uncheckedCast
|
import net.mamoe.mirai.utils.uncheckedCast
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
import kotlin.concurrent.read
|
import kotlin.concurrent.read
|
||||||
@ -54,14 +55,24 @@ internal interface PipelineContext {
|
|||||||
val isConsumed: Boolean
|
val isConsumed: Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the input as consumed so that there will not be warnings like 'Unknown type xxx'. This will not stop the pipeline.
|
* Marks the input as consumed so that there will not be warnings like 'Unknown type xxx'. This will not stop the pipeline.
|
||||||
*
|
*
|
||||||
* If this is executed, make sure you provided all information important for debugging.
|
* If this is executed, make sure you provided all information important for debugging.
|
||||||
*
|
*
|
||||||
* You need to invoke [markAsConsumed] if your implementation includes some `else` branch which covers all situations,
|
* You need to invoke [markAsConsumed] if your implementation includes some `else` branch which covers all situations,
|
||||||
* and throws a [contextualBugReportException] or logs something.
|
* and throws a [contextualBugReportException] or logs something.
|
||||||
*/
|
*/
|
||||||
fun markAsConsumed()
|
@ConsumptionMarker
|
||||||
|
fun NoticeProcessor.markAsConsumed()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the input as not consumed, if it was marked by this [NoticeProcessor].
|
||||||
|
*/
|
||||||
|
@ConsumptionMarker
|
||||||
|
fun NoticeProcessor.markNotConsumed()
|
||||||
|
|
||||||
|
@DslMarker
|
||||||
|
annotation class ConsumptionMarker // to give an explicit color.
|
||||||
|
|
||||||
|
|
||||||
val collected: Collection<Packet>
|
val collected: Collection<Packet>
|
||||||
@ -89,13 +100,16 @@ internal interface PipelineContext {
|
|||||||
* @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 [fire]).
|
||||||
*/
|
*/
|
||||||
suspend fun fire(data: Any?): Collection<Packet>
|
suspend fun fire(data: Any?): Collection<Packet>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val KEY_FROM_SYNC = TypeKey<Boolean>("fromSync")
|
||||||
|
val PipelineContext.fromSync get() = attributes[KEY_FROM_SYNC]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline val PipelineContext.context get() = this
|
internal inline val PipelineContext.context get() = this
|
||||||
|
|
||||||
internal class NoticeProcessorPipelineImpl(
|
internal class NoticeProcessorPipelineImpl : NoticeProcessorPipeline {
|
||||||
private val logger: MiraiLogger,
|
|
||||||
) : NoticeProcessorPipeline {
|
|
||||||
private val processors = ArrayList<NoticeProcessor>()
|
private val processors = ArrayList<NoticeProcessor>()
|
||||||
private val processorsLock = ReentrantReadWriteLock()
|
private val processorsLock = ReentrantReadWriteLock()
|
||||||
|
|
||||||
@ -110,9 +124,17 @@ internal class NoticeProcessorPipelineImpl(
|
|||||||
override val bot: QQAndroidBot, override val attributes: TypeSafeMap,
|
override val bot: QQAndroidBot, override val attributes: TypeSafeMap,
|
||||||
) : PipelineContext {
|
) : PipelineContext {
|
||||||
|
|
||||||
override var isConsumed: Boolean = false
|
private val consumers: Stack<NoticeProcessor> = Stack()
|
||||||
override fun markAsConsumed() {
|
|
||||||
isConsumed = true
|
override val isConsumed: Boolean = consumers.isNotEmpty()
|
||||||
|
override fun NoticeProcessor.markAsConsumed() {
|
||||||
|
consumers.push(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun NoticeProcessor.markNotConsumed() {
|
||||||
|
if (consumers.peek() === this) {
|
||||||
|
consumers.pop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val collected = ConcurrentLinkedQueue<Packet>()
|
override val collected = ConcurrentLinkedQueue<Packet>()
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/master/LICENSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.mamoe.mirai.internal.network.notice
|
|
||||||
|
|
||||||
import net.mamoe.mirai.internal.message.contextualBugReportException
|
|
||||||
import net.mamoe.mirai.internal.network.components.PipelineContext
|
|
||||||
import net.mamoe.mirai.internal.network.components.SimpleNoticeProcessor
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo
|
|
||||||
import net.mamoe.mirai.internal.utils._miraiContentToString
|
|
||||||
import net.mamoe.mirai.utils.read
|
|
||||||
|
|
||||||
internal class BinaryMessageProcessor : SimpleNoticeProcessor<PbMsgInfo>(type()), NewContactSupport {
|
|
||||||
override suspend fun PipelineContext.processImpl(data: PbMsgInfo) {
|
|
||||||
data.msgData.read<Unit> {
|
|
||||||
when (data.msgType) {
|
|
||||||
44 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
34 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
when {
|
|
||||||
data.msgType == 529 && data.msgSubtype == 9 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw contextualBugReportException(
|
|
||||||
"解析 OnlinePush.PbPushTransMsg, msgType=${data.msgType}",
|
|
||||||
data._miraiContentToString(),
|
|
||||||
null,
|
|
||||||
"并描述此时机器人是否被踢出, 或是否有成员列表变更等动作."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -86,6 +86,7 @@ internal class FriendNoticeProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgType0x210) = data.context {
|
override suspend fun PipelineContext.processImpl(data: MsgType0x210) = data.context {
|
||||||
|
markAsConsumed()
|
||||||
when (data.uSubMsgType) {
|
when (data.uSubMsgType) {
|
||||||
0xB3L -> {
|
0xB3L -> {
|
||||||
// 08 01 12 52 08 A2 FF 8C F0 03 10 00 1D 15 3D 90 5E 22 2E E6 88 91 E4 BB AC E5 B7 B2 E7 BB 8F E6 98 AF E5 A5 BD E5 8F 8B E5 95 A6 EF BC 8C E4 B8 80 E8 B5 B7 E6 9D A5 E8 81 8A E5 A4 A9 E5 90 A7 21 2A 09 48 69 6D 31 38 38 6D 6F 65 30 07 38 03 48 DD F1 92 B7 07
|
// 08 01 12 52 08 A2 FF 8C F0 03 10 00 1D 15 3D 90 5E 22 2E E6 88 91 E4 BB AC E5 B7 B2 E7 BB 8F E6 98 AF E5 A5 BD E5 8F 8B E5 95 A6 EF BC 8C E4 B8 80 E8 B5 B7 E6 9D A5 E8 81 8A E5 A4 A9 E5 90 A7 21 2A 09 48 69 6D 31 38 38 6D 6F 65 30 07 38 03 48 DD F1 92 B7 07
|
||||||
@ -111,9 +112,8 @@ internal class FriendNoticeProcessor(
|
|||||||
val body = vProtobuf.loadAs(SubMsgType0x115.MsgBody.serializer())
|
val body = vProtobuf.loadAs(SubMsgType0x115.MsgBody.serializer())
|
||||||
handleInputStatusChanged(body)
|
handleInputStatusChanged(body)
|
||||||
}
|
}
|
||||||
else -> return
|
else -> markNotConsumed()
|
||||||
}
|
}
|
||||||
markAsConsumed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PipelineContext.handleInputStatusChanged(body: SubMsgType0x115.MsgBody) {
|
private fun PipelineContext.handleInputStatusChanged(body: SubMsgType0x115.MsgBody) {
|
||||||
|
@ -60,6 +60,7 @@ internal class GroupListNoticeProcessor(
|
|||||||
|
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgType0x210) {
|
override suspend fun PipelineContext.processImpl(data: MsgType0x210) {
|
||||||
if (data.uSubMsgType != 0x44L) return
|
if (data.uSubMsgType != 0x44L) return
|
||||||
|
markAsConsumed()
|
||||||
val msg = data.vProtobuf.loadAs(Submsgtype0x44.Submsgtype0x44.MsgBody.serializer())
|
val msg = data.vProtobuf.loadAs(Submsgtype0x44.Submsgtype0x44.MsgBody.serializer())
|
||||||
if (msg.msgGroupMsgSync == null) return
|
if (msg.msgGroupMsgSync == null) return
|
||||||
|
|
||||||
@ -328,34 +329,7 @@ internal class GroupListNoticeProcessor(
|
|||||||
handleLeave(target, kind, operator, groupUin)
|
handleLeave(target, kind, operator, groupUin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> markNotConsumed()
|
||||||
when {
|
|
||||||
data.msgType == 529 && data.msgSubtype == 9 -> {
|
|
||||||
/*
|
|
||||||
PbMsgInfo#1773430973 {
|
|
||||||
fromUin=0x0000000026BA1173(649728371)
|
|
||||||
generalFlag=0x00000001(1)
|
|
||||||
msgData=0A 07 70 72 69 6E 74 65 72 10 02 1A CD 02 0A 1F 53 61 6D 73 75 6E 67 20 4D 4C 2D 31 38 36 30 20 53 65 72 69 65 73 20 28 55 53 42 30 30 31 29 0A 16 4F 6E 65 4E 6F 74 65 20 66 6F 72 20 57 69 6E 64 6F 77 73 20 31 30 0A 19 50 68 61 6E 74 6F 6D 20 50 72 69 6E 74 20 74 6F 20 45 76 65 72 6E 6F 74 65 0A 11 4F 6E 65 4E 6F 74 65 20 28 44 65 73 6B 74 6F 70 29 0A 1D 4D 69 63 72 6F 73 6F 66 74 20 58 50 53 20 44 6F 63 75 6D 65 6E 74 20 57 72 69 74 65 72 0A 16 4D 69 63 72 6F 73 6F 66 74 20 50 72 69 6E 74 20 74 6F 20 50 44 46 0A 15 46 6F 78 69 74 20 50 68 61 6E 74 6F 6D 20 50 72 69 6E 74 65 72 0A 03 46 61 78 32 09 0A 03 6A 70 67 10 01 18 00 32 0A 0A 04 6A 70 65 67 10 01 18 00 32 09 0A 03 70 6E 67 10 01 18 00 32 09 0A 03 67 69 66 10 01 18 00 32 09 0A 03 62 6D 70 10 01 18 00 32 09 0A 03 64 6F 63 10 01 18 01 32 0A 0A 04 64 6F 63 78 10 01 18 01 32 09 0A 03 74 78 74 10 00 18 00 32 09 0A 03 70 64 66 10 01 18 01 32 09 0A 03 70 70 74 10 01 18 01 32 0A 0A 04 70 70 74 78 10 01 18 01 32 09 0A 03 78 6C 73 10 01 18 01 32 0A 0A 04 78 6C 73 78 10 01 18 01
|
|
||||||
msgSeq=0x00001AFF(6911)
|
|
||||||
msgSubtype=0x00000009(9)
|
|
||||||
msgTime=0x5FDF21A3(1608458659)
|
|
||||||
msgType=0x00000211(529)
|
|
||||||
msgUid=0x010000005FDEE04C(72057595646369868)
|
|
||||||
realMsgTime=0x5FDF21A3(1608458659)
|
|
||||||
svrIp=0x3E689409(1047041033)
|
|
||||||
toUin=0x0000000026BA1173(649728371)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw contextualBugReportException(
|
|
||||||
"解析 OnlinePush.PbPushTransMsg, msgType=${data.msgType}",
|
|
||||||
data._miraiContentToString(),
|
|
||||||
null,
|
|
||||||
"并描述此时机器人是否被踢出, 或是否有成员列表变更等动作."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,4 +450,52 @@ toUin=0x0000000026BA1173(649728371)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// backup, copied from old code
|
||||||
|
/*
|
||||||
|
34 -> { // 主动入群
|
||||||
|
|
||||||
|
// 回答了问题, 还需要管理员审核
|
||||||
|
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 82 00 30 45 41 31 30 35 35 42 44 39 39 42 35 37 46 44 31 41 31 46 36 42 43 42 43 33 43 42 39 34 34 38 31 33 34 42 36 31 46 38 45 43 39 38 38 43 39 37 33
|
||||||
|
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 02 00 30 44 44 41 43 44 33 35 43 31 39 34 30 46 42 39 39 34 46 43 32 34 43 39 32 33 39 31 45 42 35 32 33 46 36 30 37 35 42 41 38 42 30 30 37 42 36 42 41
|
||||||
|
// 回答正确问题, 直接加入
|
||||||
|
|
||||||
|
// 27 0B 60 E7 01 76 E4 B8 DD 82 00 30 43 37 37 39 41 38 32 44 38 33 30 35 37 38 31 33 37 45 42 39 35 43 42 45 36 45 43 38 36 34 38 44 34 35 44 42 33 44 45 37 34 41 36 30 33 37 46 45
|
||||||
|
// 提交验证消息加入, 需要审核
|
||||||
|
|
||||||
|
// 被踢了??
|
||||||
|
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 83 3E 03 3F A2 06 B4 B4 BD A8 D5 DF 00 30 46 46 32 33 36 39 35 33 31 37 42 44 46 37 43 36 39 34 37 41 45 38 39 43 45 43 42 46 33 41 37 35 39 34 39 45 36 37 33 37 31 41 39 44 33 33 45 33
|
||||||
|
|
||||||
|
/*
|
||||||
|
// 搜索后直接加入群
|
||||||
|
|
||||||
|
soutv 17:43:32 : 33类型的content = 27 0B 60 E7 01 07 6E 47 BA 82 3E 03 3F A2 06 B4 B4 BD A8 D5 DF 00 30 32 30 39 39 42 39 41 46 32 39 41 35 42 33 46 34 32 30 44 36 44 36 39 35 44 38 45 34 35 30 46 30 45 30 38 45 31 41 39 42 46 46 45 32 30 32 34 35
|
||||||
|
soutv 17:43:32 : 主动入群content = 2A 3D F5 69 01 35 D7 10 EA 83 4C EF 4F DD 06 B9 DC C0 ED D4 B1 00 30 37 41 39 31 39 34 31 41 30 37 46 38 32 31 39 39 43 34 35 46 39 30 36 31 43 37 39 37 33 39 35 43 34 44 36 31 33 43 31 35 42 37 32 45 46 43 43 36
|
||||||
|
*/
|
||||||
|
|
||||||
|
val group = bot.getGroupByUinOrNull(msgHead.fromUin)
|
||||||
|
group ?: return
|
||||||
|
|
||||||
|
msgBody.msgContent.soutv("主动入群content")
|
||||||
|
|
||||||
|
if (msgBody.msgContent.read {
|
||||||
|
discardExact(4) // group code
|
||||||
|
discardExact(1) // 1
|
||||||
|
discardExact(4) // requester uin
|
||||||
|
readByte().toInt().and(0xff)
|
||||||
|
// 0x02: 回答正确问题直接加入
|
||||||
|
// 0x82: 回答了问题, 或者有验证消息, 需要管理员审核
|
||||||
|
// 0x83: 回答正确问题直接加入
|
||||||
|
} != 0x82) {
|
||||||
|
|
||||||
|
if (group.members.contains(msgHead.authUin)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||||
|
return MemberJoinEvent.Active(group.newMember(getNewMemberInfo())
|
||||||
|
.also { group.members.delegate.addLast(it) })
|
||||||
|
} else return
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
@ -109,8 +109,14 @@ internal class OtherClientNoticeProcessor : MixedNoticeProcessor() {
|
|||||||
*/
|
*/
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg) = data.context {
|
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg) = data.context {
|
||||||
if (msgHead.msgType != 529) return
|
if (msgHead.msgType != 529) return
|
||||||
|
|
||||||
|
// top_package/awbk.java:3765
|
||||||
markAsConsumed() // todo check
|
markAsConsumed() // todo check
|
||||||
if (msgHead.c2cCmd != 7) return
|
if (msgHead.c2cCmd != 7) {
|
||||||
|
// 各种垃圾
|
||||||
|
// 08 04 12 1E 08 E9 07 10 B7 F7 8B 80 02 18 E9 07 20 00 28 DD F1 92 B7 07 30 DD F1 92 B7 07 48 02 50 03 32 1E 08 88 80 F8 92 CD 84 80 80 10 10 01 18 00 20 01 2A 0C 0A 0A 08 01 12 06 E5 95 8A E5 95 8A
|
||||||
|
return
|
||||||
|
}
|
||||||
val body = msgBody.msgContent.loadAs(SubMsgType0x7.MsgBody.serializer())
|
val body = msgBody.msgContent.loadAs(SubMsgType0x7.MsgBody.serializer())
|
||||||
|
|
||||||
val textMsg =
|
val textMsg =
|
||||||
|
@ -15,9 +15,9 @@ import net.mamoe.mirai.internal.contact.*
|
|||||||
import net.mamoe.mirai.internal.getGroupByUin
|
import net.mamoe.mirai.internal.getGroupByUin
|
||||||
import net.mamoe.mirai.internal.message.toMessageChainOnline
|
import net.mamoe.mirai.internal.message.toMessageChainOnline
|
||||||
import net.mamoe.mirai.internal.network.components.PipelineContext
|
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.SimpleNoticeProcessor
|
||||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
||||||
import net.mamoe.mirai.internal.network.notice.SystemMessageProcessor.Companion.fromSync
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||||
import net.mamoe.mirai.utils.context
|
import net.mamoe.mirai.utils.context
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ import net.mamoe.mirai.utils.context
|
|||||||
*/
|
*/
|
||||||
internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg>(type()) {
|
internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg>(type()) {
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg) = data.context {
|
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg) = data.context {
|
||||||
|
markAsConsumed()
|
||||||
if (msgHead.fromUin == bot.id && fromSync) {
|
if (msgHead.fromUin == bot.id && fromSync) {
|
||||||
// Bot send message to himself? or from other client? I am not the implementer.
|
// Bot send message to himself? or from other client? I am not the implementer.
|
||||||
bot.client.sendFriendMessageSeq.updateIfSmallerThan(msgHead.msgSeq)
|
bot.client.sendFriendMessageSeq.updateIfSmallerThan(msgHead.msgSeq)
|
||||||
@ -47,7 +48,6 @@ internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg
|
|||||||
208, // friend ptt, maybe also support stranger
|
208, // friend ptt, maybe also support stranger
|
||||||
-> {
|
-> {
|
||||||
handlePrivateMessage(data, bot.getFriend(senderUin) ?: bot.getStranger(senderUin) ?: return)
|
handlePrivateMessage(data, bot.getFriend(senderUin) ?: bot.getStranger(senderUin) ?: return)
|
||||||
markAsConsumed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
141, // group temp
|
141, // group temp
|
||||||
@ -55,7 +55,9 @@ internal class PrivateMessageNoticeProcessor : SimpleNoticeProcessor<MsgComm.Msg
|
|||||||
val tmpHead = msgHead.c2cTmpMsgHead ?: return
|
val tmpHead = msgHead.c2cTmpMsgHead ?: return
|
||||||
val group = bot.getGroupByUin(tmpHead.groupUin) ?: return
|
val group = bot.getGroupByUin(tmpHead.groupUin) ?: return
|
||||||
handlePrivateMessage(data, group[senderUin] ?: return)
|
handlePrivateMessage(data, group[senderUin] ?: return)
|
||||||
markAsConsumed()
|
}
|
||||||
|
else -> {
|
||||||
|
markNotConsumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/master/LICENSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.mamoe.mirai.internal.network.notice
|
|
||||||
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import net.mamoe.mirai.internal.network.components.ContactUpdater
|
|
||||||
import net.mamoe.mirai.internal.network.components.MsgCommonMsgProcessor
|
|
||||||
import net.mamoe.mirai.internal.network.components.PipelineContext
|
|
||||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
|
||||||
import net.mamoe.mirai.internal.network.handler.logger
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.NewContact
|
|
||||||
import net.mamoe.mirai.utils.TypeKey
|
|
||||||
import net.mamoe.mirai.utils.debug
|
|
||||||
import net.mamoe.mirai.utils.toUHexString
|
|
||||||
|
|
||||||
internal class SystemMessageProcessor : MsgCommonMsgProcessor(), NewContactSupport {
|
|
||||||
companion object {
|
|
||||||
val KEY_FROM_SYNC = TypeKey<Boolean>("fromSync")
|
|
||||||
val PipelineContext.fromSync get() = attributes[KEY_FROM_SYNC]
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg): Unit = data.run {
|
|
||||||
// TODO: 2021/6/26 extract logic into multiple processors
|
|
||||||
when (msgHead.msgType) {
|
|
||||||
33 -> bot.components[ContactUpdater].groupListModifyLock.withLock {
|
|
||||||
}
|
|
||||||
|
|
||||||
34 -> { // 与 33 重复
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
38 -> bot.components[ContactUpdater].groupListModifyLock.withLock { // 建群
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
85 -> bot.components[ContactUpdater].groupListModifyLock.withLock { // 其他客户端入群
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
34 -> { // 主动入群
|
|
||||||
|
|
||||||
// 回答了问题, 还需要管理员审核
|
|
||||||
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 82 00 30 45 41 31 30 35 35 42 44 39 39 42 35 37 46 44 31 41 31 46 36 42 43 42 43 33 43 42 39 34 34 38 31 33 34 42 36 31 46 38 45 43 39 38 38 43 39 37 33
|
|
||||||
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 02 00 30 44 44 41 43 44 33 35 43 31 39 34 30 46 42 39 39 34 46 43 32 34 43 39 32 33 39 31 45 42 35 32 33 46 36 30 37 35 42 41 38 42 30 30 37 42 36 42 41
|
|
||||||
// 回答正确问题, 直接加入
|
|
||||||
|
|
||||||
// 27 0B 60 E7 01 76 E4 B8 DD 82 00 30 43 37 37 39 41 38 32 44 38 33 30 35 37 38 31 33 37 45 42 39 35 43 42 45 36 45 43 38 36 34 38 44 34 35 44 42 33 44 45 37 34 41 36 30 33 37 46 45
|
|
||||||
// 提交验证消息加入, 需要审核
|
|
||||||
|
|
||||||
// 被踢了??
|
|
||||||
// msgContent=27 0B 60 E7 01 76 E4 B8 DD 83 3E 03 3F A2 06 B4 B4 BD A8 D5 DF 00 30 46 46 32 33 36 39 35 33 31 37 42 44 46 37 43 36 39 34 37 41 45 38 39 43 45 43 42 46 33 41 37 35 39 34 39 45 36 37 33 37 31 41 39 44 33 33 45 33
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 搜索后直接加入群
|
|
||||||
|
|
||||||
soutv 17:43:32 : 33类型的content = 27 0B 60 E7 01 07 6E 47 BA 82 3E 03 3F A2 06 B4 B4 BD A8 D5 DF 00 30 32 30 39 39 42 39 41 46 32 39 41 35 42 33 46 34 32 30 44 36 44 36 39 35 44 38 45 34 35 30 46 30 45 30 38 45 31 41 39 42 46 46 45 32 30 32 34 35
|
|
||||||
soutv 17:43:32 : 主动入群content = 2A 3D F5 69 01 35 D7 10 EA 83 4C EF 4F DD 06 B9 DC C0 ED D4 B1 00 30 37 41 39 31 39 34 31 41 30 37 46 38 32 31 39 39 43 34 35 46 39 30 36 31 43 37 39 37 33 39 35 43 34 44 36 31 33 43 31 35 42 37 32 45 46 43 43 36
|
|
||||||
*/
|
|
||||||
|
|
||||||
val group = bot.getGroupByUinOrNull(msgHead.fromUin)
|
|
||||||
group ?: return
|
|
||||||
|
|
||||||
msgBody.msgContent.soutv("主动入群content")
|
|
||||||
|
|
||||||
if (msgBody.msgContent.read {
|
|
||||||
discardExact(4) // group code
|
|
||||||
discardExact(1) // 1
|
|
||||||
discardExact(4) // requester uin
|
|
||||||
readByte().toInt().and(0xff)
|
|
||||||
// 0x02: 回答正确问题直接加入
|
|
||||||
// 0x82: 回答了问题, 或者有验证消息, 需要管理员审核
|
|
||||||
// 0x83: 回答正确问题直接加入
|
|
||||||
} != 0x82) {
|
|
||||||
|
|
||||||
if (group.members.contains(msgHead.authUin)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
|
||||||
return MemberJoinEvent.Active(group.newMember(getNewMemberInfo())
|
|
||||||
.also { group.members.delegate.addLast(it) })
|
|
||||||
} else return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//167 单向好友
|
|
||||||
166, 167 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
208 -> {
|
|
||||||
// friend ptt
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
529 -> {
|
|
||||||
|
|
||||||
// top_package/awbk.java:3765
|
|
||||||
|
|
||||||
when (msgHead.c2cCmd) {
|
|
||||||
// other client sync
|
|
||||||
7 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 各种垃圾
|
|
||||||
// 08 04 12 1E 08 E9 07 10 B7 F7 8B 80 02 18 E9 07 20 00 28 DD F1 92 B7 07 30 DD F1 92 B7 07 48 02 50 03 32 1E 08 88 80 F8 92 CD 84 80 80 10 10 01 18 00 20 01 2A 0C 0A 0A 08 01 12 06 E5 95 8A E5 95 8A
|
|
||||||
}
|
|
||||||
141 -> {
|
|
||||||
|
|
||||||
if (!bot.components[SsoProcessor].firstLoginSucceed || msgHead.fromUin == bot.id && !fromSync) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
84, 87 -> { // 请求入群验证 和 被要求入群
|
|
||||||
bot.network.run {
|
|
||||||
NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
187 -> { // 请求加好友验证
|
|
||||||
bot.network.run {
|
|
||||||
NewContact.SystemMsgNewFriend(bot.client).sendWithoutExpect()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
732 -> {
|
|
||||||
// unknown
|
|
||||||
// 前 4 byte 是群号
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//陌生人添加信息
|
|
||||||
191 -> {
|
|
||||||
TODO("removed")
|
|
||||||
}
|
|
||||||
// 732: 27 0B 60 E7 0C 01 3E 03 3F A2 5E 90 60 E2 00 01 44 71 47 90 00 00 02 58
|
|
||||||
// 732: 27 0B 60 E7 11 00 40 08 07 20 E7 C1 AD B8 02 5A 36 08 B4 E7 E0 F0 09 1A 1A 08 9C D4 16 10 F7 D2 D8 F5 05 18 D0 E2 85 F4 06 20 00 28 00 30 B4 E7 E0 F0 09 2A 0E 08 00 12 0A 08 9C D4 16 10 00 18 01 20 00 30 00 38 00
|
|
||||||
// 732: 27 0B 60 E7 11 00 33 08 07 20 E7 C1 AD B8 02 5A 29 08 EE 97 85 E9 01 1A 19 08 EE D6 16 10 FF F2 D8 F5 05 18 E9 E7 A3 05 20 00 28 00 30 EE 97 85 E9 01 2A 02 08 00 30 00 38 00
|
|
||||||
else -> {
|
|
||||||
bot.network.logger.debug { "unknown PbGetMsg type ${msgHead.msgType}, data=${msgBody.msgContent.toUHexString()}" }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// kotlin bug, don't remove
|
|
||||||
private inline fun kotlinx.atomicfu.AtomicInt.loop(action: (Int) -> Unit): Nothing {
|
|
||||||
while (true) {
|
|
||||||
action(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* 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/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.internal.network.notice
|
||||||
|
|
||||||
|
import net.mamoe.mirai.internal.message.contextualBugReportException
|
||||||
|
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.jce.MsgInfo
|
||||||
|
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
|
||||||
|
import net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushStatus
|
||||||
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||||
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
|
||||||
|
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.packet.chat.NewContact
|
||||||
|
import net.mamoe.mirai.internal.utils._miraiContentToString
|
||||||
|
import net.mamoe.mirai.utils.MiraiLogger
|
||||||
|
import net.mamoe.mirai.utils.debug
|
||||||
|
import net.mamoe.mirai.utils.toUHexString
|
||||||
|
|
||||||
|
internal class UnconsumedNoticesAlerter(
|
||||||
|
private val logger: MiraiLogger,
|
||||||
|
) : MixedNoticeProcessor() {
|
||||||
|
override suspend fun PipelineContext.processImpl(data: MsgInfo) {
|
||||||
|
if (isConsumed) return
|
||||||
|
logger.debug { "Unknown kind ${data.shMsgType.toInt()}, data=${data.vMsg.toUHexString()}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: MsgType0x210) {
|
||||||
|
if (isConsumed) return
|
||||||
|
when (data.uSubMsgType) {
|
||||||
|
0x26L, // VIP 进群提示
|
||||||
|
0x111L, // 提示共同好友
|
||||||
|
0xD4L, // bot 在其他客户端被踢或主动退出而同步情况
|
||||||
|
-> {
|
||||||
|
// Network(1994701021) 16:03:54 : unknown group 528 type 0x0000000000000026, data: 08 01 12 40 0A 06 08 F4 EF BB 8F 04 10 E7 C1 AD B8 02 18 01 22 2C 10 01 1A 1A 18 B4 DC F8 9B 0C 20 E7 C1 AD B8 02 28 06 30 02 A2 01 04 08 93 D6 03 A8 01 08 20 00 28 00 32 08 18 01 20 FE AF AF F5 05 28 00
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
0xE2L -> {
|
||||||
|
// unknown
|
||||||
|
|
||||||
|
// 0A 35 08 00 10 A2 FF 8C F0 03 1A 1B E5 90 8C E6 84 8F E4 BD A0 E7 9A 84 E5 8A A0 E5 A5 BD E5 8F 8B E8 AF B7 E6 B1 82 22 0C E6 BD 9C E6 B1 9F E7 BE A4 E5 8F 8B 28 01
|
||||||
|
// vProtobuf.loadAs(Msgtype0x210.serializer())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
logger.debug { "Unknown group 528 type 0x${data.uSubMsgType.toUHexString("")}, data: " + data.vProtobuf.toUHexString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: MsgType0x2DC) {
|
||||||
|
if (isConsumed) return
|
||||||
|
logger.debug { "Unknown group 732 type ${data.kind}, data: " + data.buf.toUHexString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: OnlinePushTrans.PbMsgInfo) {
|
||||||
|
if (isConsumed) return
|
||||||
|
when {
|
||||||
|
data.msgType == 529 && data.msgSubtype == 9 -> {
|
||||||
|
/*
|
||||||
|
PbMsgInfo#1773430973 {
|
||||||
|
fromUin=0x0000000026BA1173(649728371)
|
||||||
|
generalFlag=0x00000001(1)
|
||||||
|
msgData=0A 07 70 72 69 6E 74 65 72 10 02 1A CD 02 0A 1F 53 61 6D 73 75 6E 67 20 4D 4C 2D 31 38 36 30 20 53 65 72 69 65 73 20 28 55 53 42 30 30 31 29 0A 16 4F 6E 65 4E 6F 74 65 20 66 6F 72 20 57 69 6E 64 6F 77 73 20 31 30 0A 19 50 68 61 6E 74 6F 6D 20 50 72 69 6E 74 20 74 6F 20 45 76 65 72 6E 6F 74 65 0A 11 4F 6E 65 4E 6F 74 65 20 28 44 65 73 6B 74 6F 70 29 0A 1D 4D 69 63 72 6F 73 6F 66 74 20 58 50 53 20 44 6F 63 75 6D 65 6E 74 20 57 72 69 74 65 72 0A 16 4D 69 63 72 6F 73 6F 66 74 20 50 72 69 6E 74 20 74 6F 20 50 44 46 0A 15 46 6F 78 69 74 20 50 68 61 6E 74 6F 6D 20 50 72 69 6E 74 65 72 0A 03 46 61 78 32 09 0A 03 6A 70 67 10 01 18 00 32 0A 0A 04 6A 70 65 67 10 01 18 00 32 09 0A 03 70 6E 67 10 01 18 00 32 09 0A 03 67 69 66 10 01 18 00 32 09 0A 03 62 6D 70 10 01 18 00 32 09 0A 03 64 6F 63 10 01 18 01 32 0A 0A 04 64 6F 63 78 10 01 18 01 32 09 0A 03 74 78 74 10 00 18 00 32 09 0A 03 70 64 66 10 01 18 01 32 09 0A 03 70 70 74 10 01 18 01 32 0A 0A 04 70 70 74 78 10 01 18 01 32 09 0A 03 78 6C 73 10 01 18 01 32 0A 0A 04 78 6C 73 78 10 01 18 01
|
||||||
|
msgSeq=0x00001AFF(6911)
|
||||||
|
msgSubtype=0x00000009(9)
|
||||||
|
msgTime=0x5FDF21A3(1608458659)
|
||||||
|
msgType=0x00000211(529)
|
||||||
|
msgUid=0x010000005FDEE04C(72057595646369868)
|
||||||
|
realMsgTime=0x5FDF21A3(1608458659)
|
||||||
|
svrIp=0x3E689409(1047041033)
|
||||||
|
toUin=0x0000000026BA1173(649728371)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw contextualBugReportException(
|
||||||
|
"解析 OnlinePush.PbPushTransMsg, msgType=${data.msgType}",
|
||||||
|
data._miraiContentToString(),
|
||||||
|
null,
|
||||||
|
"并描述此时机器人是否被踢出, 或是否有成员列表变更等动作.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: MsgOnlinePush.PbPushMsg) {
|
||||||
|
if (isConsumed) return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: MsgComm.Msg) {
|
||||||
|
if (isConsumed) return
|
||||||
|
when (data.msgHead.msgType) {
|
||||||
|
732 -> {
|
||||||
|
// 732: 27 0B 60 E7 0C 01 3E 03 3F A2 5E 90 60 E2 00 01 44 71 47 90 00 00 02 58
|
||||||
|
// 732: 27 0B 60 E7 11 00 40 08 07 20 E7 C1 AD B8 02 5A 36 08 B4 E7 E0 F0 09 1A 1A 08 9C D4 16 10 F7 D2 D8 F5 05 18 D0 E2 85 F4 06 20 00 28 00 30 B4 E7 E0 F0 09 2A 0E 08 00 12 0A 08 9C D4 16 10 00 18 01 20 00 30 00 38 00
|
||||||
|
// 732: 27 0B 60 E7 11 00 33 08 07 20 E7 C1 AD B8 02 5A 29 08 EE 97 85 E9 01 1A 19 08 EE D6 16 10 FF F2 D8 F5 05 18 E9 E7 A3 05 20 00 28 00 30 EE 97 85 E9 01 2A 02 08 00 30 00 38 00
|
||||||
|
|
||||||
|
// unknown
|
||||||
|
// 前 4 byte 是群号
|
||||||
|
}
|
||||||
|
84, 87 -> { // 请求入群验证 和 被要求入群
|
||||||
|
bot.network.run {
|
||||||
|
NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
187 -> { // 请求加好友验证
|
||||||
|
bot.network.run {
|
||||||
|
NewContact.SystemMsgNewFriend(bot.client).sendWithoutExpect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
logger.debug { "unknown PbGetMsg type ${data.msgHead.msgType}, data=${data.msgBody.msgContent.toUHexString()}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: Structmsg.StructMsg) {
|
||||||
|
if (isConsumed) return
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun PipelineContext.processImpl(data: RequestPushStatus) {
|
||||||
|
if (isConsumed) return
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
}
|
@ -19,18 +19,14 @@ import net.mamoe.mirai.internal.network.components.SimpleNoticeProcessor
|
|||||||
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgInfo
|
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgInfo
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
|
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
|
||||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||||
import net.mamoe.mirai.utils.MiraiLogger
|
|
||||||
import net.mamoe.mirai.utils.debug
|
|
||||||
import net.mamoe.mirai.utils.read
|
import net.mamoe.mirai.utils.read
|
||||||
import net.mamoe.mirai.utils.toUHexString
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes [MsgInfo] and re-fire [MsgType0x210] or [MsgType0x2DC]
|
* Decodes [MsgInfo] and re-fire [MsgType0x210] or [MsgType0x2DC]
|
||||||
*/
|
*/
|
||||||
internal class MsgInfoDecoder(
|
internal class MsgInfoDecoder : SimpleNoticeProcessor<MsgInfo>(type()) {
|
||||||
private val logger: MiraiLogger,
|
|
||||||
) : SimpleNoticeProcessor<MsgInfo>(type()) {
|
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgInfo) {
|
override suspend fun PipelineContext.processImpl(data: MsgInfo) {
|
||||||
|
markAsConsumed()
|
||||||
when (data.shMsgType.toUShort().toInt()) {
|
when (data.shMsgType.toUShort().toInt()) {
|
||||||
// 528
|
// 528
|
||||||
0x210 -> fire(data.vMsg.loadAs(MsgType0x210.serializer()))
|
0x210 -> fire(data.vMsg.loadAs(MsgType0x210.serializer()))
|
||||||
@ -47,10 +43,7 @@ internal class MsgInfoDecoder(
|
|||||||
fire(MsgType0x2DC(kind, group, this.readBytes()))
|
fire(MsgType0x2DC(kind, group, this.readBytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else -> markNotConsumed()
|
||||||
else -> {
|
|
||||||
logger.debug { "Unknown kind ${data.shMsgType.toInt()}, data=${data.vMsg.toUHexString()}" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,5 +51,5 @@ internal class MsgInfoDecoder(
|
|||||||
internal class MsgType0x2DC(
|
internal class MsgType0x2DC(
|
||||||
val kind: Int, // inner kind, read from vMsg
|
val kind: Int, // inner kind, read from vMsg
|
||||||
val group: GroupImpl,
|
val group: GroupImpl,
|
||||||
val buf: ByteArray
|
val buf: ByteArray,
|
||||||
)
|
)
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/master/LICENSE
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.mamoe.mirai.internal.network.notice.decoders
|
|
||||||
|
|
||||||
import net.mamoe.mirai.internal.network.components.PipelineContext
|
|
||||||
import net.mamoe.mirai.internal.network.components.SimpleNoticeProcessor
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
|
|
||||||
|
|
||||||
internal class MsgType0x210Decoder : SimpleNoticeProcessor<MsgType0x210>(type()) {
|
|
||||||
override suspend fun PipelineContext.processImpl(data: MsgType0x210) {
|
|
||||||
when (data.uSubMsgType) {
|
|
||||||
0x8AL -> {
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,8 +24,7 @@ import net.mamoe.mirai.internal.QQAndroidBot
|
|||||||
import net.mamoe.mirai.internal.network.MultiPacket
|
import net.mamoe.mirai.internal.network.MultiPacket
|
||||||
import net.mamoe.mirai.internal.network.Packet
|
import net.mamoe.mirai.internal.network.Packet
|
||||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||||
import net.mamoe.mirai.internal.network.components.NoticeProcessorPipeline.Companion.noticeProcessorPipeline
|
import net.mamoe.mirai.internal.network.components.PipelineContext.Companion.KEY_FROM_SYNC
|
||||||
import net.mamoe.mirai.internal.network.notice.SystemMessageProcessor
|
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgSvc
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgSvc
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
|
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
|
||||||
@ -152,14 +151,12 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
|||||||
QQAndroidClient.MessageSvcSyncData.PbGetMessageSyncId(
|
QQAndroidClient.MessageSvcSyncData.PbGetMessageSyncId(
|
||||||
uid = msg.msgHead.msgUid,
|
uid = msg.msgHead.msgUid,
|
||||||
sequence = msg.msgHead.msgSeq,
|
sequence = msg.msgHead.msgSeq,
|
||||||
time = msg.msgHead.msgTime
|
time = msg.msgHead.msgTime,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.flatMapConcat { msg ->
|
.map { msg ->
|
||||||
bot.components.noticeProcessorPipeline
|
bot.processPacketThroughPipeline(msg, KEY_FROM_SYNC to false)
|
||||||
.process(bot, msg, SystemMessageProcessor.KEY_FROM_SYNC to false)
|
|
||||||
.asFlow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val list: List<Packet> = messages.toList()
|
val list: List<Packet> = messages.toList()
|
||||||
|
@ -13,7 +13,7 @@ import kotlinx.io.core.ByteReadPacket
|
|||||||
import net.mamoe.mirai.internal.QQAndroidBot
|
import net.mamoe.mirai.internal.QQAndroidBot
|
||||||
import net.mamoe.mirai.internal.network.Packet
|
import net.mamoe.mirai.internal.network.Packet
|
||||||
import net.mamoe.mirai.internal.network.components.NoticeProcessorPipeline.Companion.noticeProcessorPipeline
|
import net.mamoe.mirai.internal.network.components.NoticeProcessorPipeline.Companion.noticeProcessorPipeline
|
||||||
import net.mamoe.mirai.internal.network.notice.SystemMessageProcessor
|
import net.mamoe.mirai.internal.network.components.PipelineContext.Companion.KEY_FROM_SYNC
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
|
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
|
||||||
import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory
|
import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory
|
||||||
import net.mamoe.mirai.internal.network.toPacket
|
import net.mamoe.mirai.internal.network.toPacket
|
||||||
@ -26,7 +26,7 @@ internal object PbC2CMsgSync : IncomingPacketFactory<Packet>(
|
|||||||
return bot.components.noticeProcessorPipeline.process(
|
return bot.components.noticeProcessorPipeline.process(
|
||||||
bot = bot,
|
bot = bot,
|
||||||
data = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer()).msg,
|
data = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer()).msg,
|
||||||
attributes = SystemMessageProcessor.KEY_FROM_SYNC to true
|
attributes = KEY_FROM_SYNC to true,
|
||||||
).toPacket()
|
).toPacket()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -446,8 +446,6 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val ignoredLambda528: Lambda528 = lambda528 { _, _ -> emptySequence() }
|
|
||||||
|
|
||||||
internal interface Lambda528 {
|
internal interface Lambda528 {
|
||||||
suspend operator fun invoke(msg: MsgType0x210, bot: QQAndroidBot, msgInfo: MsgInfo): Sequence<Packet>
|
suspend operator fun invoke(msg: MsgType0x210, bot: QQAndroidBot, msgInfo: MsgInfo): Sequence<Packet>
|
||||||
}
|
}
|
||||||
@ -526,44 +524,6 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Network(1994701021) 16:03:54 : unknown group 528 type 0x0000000000000026, data: 08 01 12 40 0A 06 08 F4 EF BB 8F 04 10 E7 C1 AD B8 02 18 01 22 2C 10 01 1A 1A 18 B4 DC F8 9B 0C 20 E7 C1 AD B8 02 28 06 30 02 A2 01 04 08 93 D6 03 A8 01 08 20 00 28 00 32 08 18 01 20 FE AF AF F5 05 28 00
|
|
||||||
// VIP 进群提示
|
|
||||||
0x26L to ignoredLambda528,
|
|
||||||
// 提示共同好友
|
|
||||||
0x111L to ignoredLambda528,
|
|
||||||
// 新好友
|
|
||||||
0xB3L to lambda528 { bot ->
|
|
||||||
TODO("removed")
|
|
||||||
},
|
|
||||||
0xE2L to lambda528 { _ ->
|
|
||||||
// TODO: unknown. maybe messages.
|
|
||||||
// 0A 35 08 00 10 A2 FF 8C F0 03 1A 1B E5 90 8C E6 84 8F E4 BD A0 E7 9A 84 E5 8A A0 E5 A5 BD E5 8F 8B E8 AF B7 E6 B1 82 22 0C E6 BD 9C E6 B1 9F E7 BE A4 E5 8F 8B 28 01
|
|
||||||
// vProtobuf.loadAs(Msgtype0x210.serializer())
|
|
||||||
|
|
||||||
return@lambda528 emptySequence()
|
|
||||||
},
|
|
||||||
0x44L to lambda528 { bot ->
|
|
||||||
TODO("removed")
|
|
||||||
},
|
|
||||||
// bot 在其他客户端被踢或主动退出而同步情况
|
|
||||||
0xD4L to lambda528 { _ ->
|
|
||||||
// this.soutv("0x210")
|
|
||||||
/* @Serializable
|
|
||||||
data class SubD4(
|
|
||||||
// ok
|
|
||||||
val uin: Long
|
|
||||||
) : ProtoBuf
|
|
||||||
|
|
||||||
val uin = vProtobuf.loadAs(SubD4.serializer()).uin
|
|
||||||
val group = bot.getGroupByUinOrNull(uin) ?: bot.getGroupOrNull(uin)
|
|
||||||
return@lambda528 if (group != null && bot.groups.delegate.remove(group)) {
|
|
||||||
group.cancel(CancellationException("Being kicked"))
|
|
||||||
sequenceOf(BotLeaveEvent.Active(group))
|
|
||||||
} else emptySequence()*/
|
|
||||||
|
|
||||||
//ignore
|
|
||||||
return@lambda528 emptySequence()
|
|
||||||
},
|
|
||||||
//戳一戳信息等
|
//戳一戳信息等
|
||||||
0x122L to lambda528 { bot, msgInfo ->
|
0x122L to lambda528 { bot, msgInfo ->
|
||||||
val body = vProtobuf.loadAs(Submsgtype0x122.Submsgtype0x122.MsgBody.serializer())
|
val body = vProtobuf.loadAs(Submsgtype0x122.Submsgtype0x122.MsgBody.serializer())
|
||||||
@ -618,10 +578,6 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//好友输入状态
|
|
||||||
0x115L to lambda528 { bot ->
|
|
||||||
TODO("removed")
|
|
||||||
},
|
|
||||||
// 群相关, ModFriendRemark, DelFriend, ModGroupProfile
|
// 群相关, ModFriendRemark, DelFriend, ModGroupProfile
|
||||||
0x27L to lambda528 { bot ->
|
0x27L to lambda528 { bot ->
|
||||||
fun ModGroupProfile.transform(bot: QQAndroidBot): Sequence<Packet> {
|
fun ModGroupProfile.transform(bot: QQAndroidBot): Sequence<Packet> {
|
||||||
|
Loading…
Reference in New Issue
Block a user