mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-10 20:20:08 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
3cbd26e263
@ -98,13 +98,14 @@ internal class GroupImpl(bot: QQAndroidBot, override val coroutineContext: Corou
|
||||
|
||||
override suspend fun sendMessage(message: MessageChain) {
|
||||
bot.network.run {
|
||||
val response = MessageSvc.PbSendMsg.ToGroup(
|
||||
bot.client,
|
||||
id,
|
||||
message
|
||||
).sendAndExpect<MessageSvc.PbSendMsg.Response>()
|
||||
check(
|
||||
MessageSvc.PbSendMsg.ToGroup(
|
||||
bot.client,
|
||||
id,
|
||||
message
|
||||
).sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
|
||||
) { "send message failed" }
|
||||
response is MessageSvc.PbSendMsg.Response.SUCCESS
|
||||
) { "send message failed: $response" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
|
||||
}
|
||||
|
||||
override fun encodeTaggedEnum(tag: Int, enumDescription: SerialDescriptor, ordinal: Int) {
|
||||
TODO()
|
||||
encodeTaggedInt(tag, ordinal)
|
||||
}
|
||||
|
||||
override fun encodeTaggedNull(tag: Int) {
|
||||
@ -332,9 +332,9 @@ class Jce private constructor(private val charset: JceCharset, context: SerialMo
|
||||
override fun decodeTaggedString(tag: Int): String = input.readString(tag)
|
||||
override fun decodeTaggedBoolean(tag: Int): Boolean = input.readBoolean(tag)
|
||||
|
||||
|
||||
override fun decodeTaggedEnum(tag: Int, enumDescription: SerialDescriptor): Int =
|
||||
TODO()
|
||||
override fun decodeTaggedEnum(tag: Int, enumDescription: SerialDescriptor): Int {
|
||||
return input.readInt(tag)
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [KSerializer.serialize] 前
|
||||
|
@ -112,6 +112,9 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
}
|
||||
}
|
||||
|
||||
//val msg = MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendAndExpect<MessageSvc.PbGetMsg.Response>()
|
||||
//println(msg.contentToString())
|
||||
|
||||
try {
|
||||
bot.logger.info("开始加载好友信息")
|
||||
var currentFriendCount = 0
|
||||
@ -347,6 +350,16 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
|
||||
private val packetReceiveLock: Mutex = Mutex()
|
||||
|
||||
/**
|
||||
* 发送一个包, 但不期待任何返回.
|
||||
*/
|
||||
suspend fun OutgoingPacket.sendWithoutExpect() {
|
||||
bot.logger.info("Send: ${this.commandName}")
|
||||
withContext(this@QQAndroidBotNetworkHandler.coroutineContext + CoroutineName("Packet sender")) {
|
||||
channel.send(delegate)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个包, 并挂起直到接收到指定的返回包或超时(3000ms)
|
||||
*/
|
||||
@ -363,19 +376,17 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
channel.send(delegate)
|
||||
}
|
||||
bot.logger.info("Send: ${this.commandName}")
|
||||
try {
|
||||
return withTimeoutOrNull(timeoutMillis) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
handler.await() as E
|
||||
// 不要 `withTimeout`. timeout 的异常会不知道去哪了.
|
||||
} ?: net.mamoe.mirai.qqandroid.utils.inline {
|
||||
error("timeout when receiving response of $commandName")
|
||||
}
|
||||
} finally {
|
||||
packetListeners.remove(handler)
|
||||
return withTimeoutOrNull(timeoutMillis) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
handler.await() as E
|
||||
// 不要 `withTimeout`. timeout 的异常会不知道去哪了.
|
||||
} ?: net.mamoe.mirai.qqandroid.utils.inline {
|
||||
error("timeout when receiving response of $commandName")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
lastException = e
|
||||
} finally {
|
||||
packetListeners.remove(handler)
|
||||
}
|
||||
}
|
||||
throw lastException!!
|
||||
|
@ -86,6 +86,8 @@ internal open class QQAndroidClient(
|
||||
var mainSigMap: Int = 16724722
|
||||
var subSigMap: Int = 0x10400 //=66,560
|
||||
|
||||
var configPushSvcPushReqSequenceId: Int = 0
|
||||
|
||||
private val _ssoSequenceId: AtomicInt = atomic(85600)
|
||||
|
||||
@MiraiInternalAPI("Do not use directly. Get from the lambda param of buildSsoPacket")
|
||||
@ -96,7 +98,10 @@ internal open class QQAndroidClient(
|
||||
val apkVersionName: ByteArray = "8.2.0".toByteArray()
|
||||
|
||||
private val messageSequenceId: AtomicInt = atomic(0)
|
||||
internal fun atomicNextMessageSequenceId(): Int = messageSequenceId.getAndIncrement()
|
||||
internal fun atomicNextMessageSequenceId(): Int = messageSequenceId.getAndAdd(2)
|
||||
|
||||
private val requestPacketRequestId: AtomicInt = atomic(1921334513)
|
||||
internal fun nextRequestPacketRequestId(): Int = requestPacketRequestId.getAndAdd(2)
|
||||
|
||||
val appClientVersion: Int = 0
|
||||
|
||||
@ -112,7 +117,6 @@ internal open class QQAndroidClient(
|
||||
class C2cMessageSyncData {
|
||||
var syncCookie: ByteArray? = null
|
||||
var pubAccountCookie = EMPTY_BYTE_ARRAY
|
||||
var syncFlag: Int = 0
|
||||
var msgCtrlBuf: ByteArray = EMPTY_BYTE_ARRAY
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,138 @@
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.data.jce
|
||||
|
||||
import kotlinx.serialization.SerialId
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.qqandroid.io.JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class BigDataChannel(
|
||||
@SerialId(0) val vBigdataIplists: List<BigDataIpList>,
|
||||
@SerialId(1) val sBigdataSigSession: ByteArray? = null,
|
||||
@SerialId(2) val sBigdataKeySession: ByteArray? = null,
|
||||
@SerialId(3) val uSigUin: Long? = null,
|
||||
@SerialId(4) val iConnectFlag: Int? = 1,
|
||||
@SerialId(5) val vBigdataPbBuf: ByteArray? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class BigDataIpInfo(
|
||||
@SerialId(0) val uType: Long,
|
||||
@SerialId(1) val sIp: String = "",
|
||||
@SerialId(2) val uPort: Long
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class BigDataIpList(
|
||||
@SerialId(0) val uServiceType: Long,
|
||||
@SerialId(1) val vIplist: List<BigDataIpInfo>,
|
||||
@SerialId(2) val netSegConfs: List<NetSegConf>? = null,
|
||||
@SerialId(3) val ufragmentSize: Long? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class ClientLogConfig(
|
||||
@SerialId(1) val type: Int,
|
||||
@SerialId(2) val timeStart: TimeStamp? = null,
|
||||
@SerialId(3) val timeFinish: TimeStamp? = null,
|
||||
@SerialId(4) val loglevel: Byte? = null,
|
||||
@SerialId(5) val cookie: Int? = null,
|
||||
@SerialId(6) val lseq: Long? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class DomainIpChannel(
|
||||
@SerialId(0) val vDomainIplists: List<DomainIpList>
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class DomainIpInfo(
|
||||
@SerialId(1) val uIp: Int,
|
||||
@SerialId(2) val uPort: Int
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class DomainIpList(
|
||||
@SerialId(0) val uDomainType: Int,
|
||||
@SerialId(1) val vIplist: List<DomainIpInfo>
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class FileStoragePushFSSvcList(
|
||||
@SerialId(0) val vUpLoadList: List<FileStorageServerListInfo>,
|
||||
@SerialId(1) val vPicDownLoadList: List<FileStorageServerListInfo>,
|
||||
@SerialId(2) val vGPicDownLoadList: List<FileStorageServerListInfo>? = null,
|
||||
@SerialId(3) val vQzoneProxyServiceList: List<FileStorageServerListInfo>? = null,
|
||||
@SerialId(4) val vUrlEncodeServiceList: List<FileStorageServerListInfo>? = null,
|
||||
@SerialId(5) val bigDataChannel: BigDataChannel? = null,
|
||||
@SerialId(6) val vVipEmotionList: List<FileStorageServerListInfo>? = null,
|
||||
@SerialId(7) val vC2CPicDownList: List<FileStorageServerListInfo>? = null,
|
||||
@SerialId(8) val fmtIPInfo: FmtIPInfo? = null,
|
||||
@SerialId(9) val domainIpChannel: DomainIpChannel? = null,
|
||||
@SerialId(10) val pttlist: ByteArray? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class FileStorageServerListInfo(
|
||||
@SerialId(1) val sIP: String = "",
|
||||
@SerialId(2) val iPort: Int
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class FmtIPInfo(
|
||||
@SerialId(0) val sGateIp: String = "",
|
||||
@SerialId(1) val iGateIpOper: Long
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class NetSegConf(
|
||||
@SerialId(0) val uint32NetType: Long? = null,
|
||||
@SerialId(1) val uint32Segsize: Long? = null,
|
||||
@SerialId(2) val uint32Segnum: Long? = null,
|
||||
@SerialId(3) val uint32Curconnnum: Long? = null
|
||||
) : JceStruct
|
||||
|
||||
@Suppress("ArrayInDataClass")
|
||||
@Serializable
|
||||
internal data class PushReq(
|
||||
@SerialId(1) val type: Int,
|
||||
@SerialId(2) val jcebuf: ByteArray,
|
||||
@SerialId(3) val seq: Long
|
||||
) : JceStruct, Packet
|
||||
|
||||
@Serializable
|
||||
internal class PushResp(
|
||||
@SerialId(1) val type: Int,
|
||||
@SerialId(2) val seq: Long,
|
||||
@SerialId(3) val jcebuf: ByteArray? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class SsoServerList(
|
||||
@SerialId(1) val v2G3GList: List<SsoServerListInfo>,
|
||||
@SerialId(3) val vWifiList: List<SsoServerListInfo>,
|
||||
@SerialId(4) val iReconnect: Int,
|
||||
@SerialId(5) val testSpeed: Byte? = null,
|
||||
@SerialId(6) val useNewList: Byte? = null,
|
||||
@SerialId(7) val iMultiConn: Int? = 1,
|
||||
@SerialId(8) val vHttp2g3glist: List<SsoServerListInfo>? = null,
|
||||
@SerialId(9) val vHttpWifilist: List<SsoServerListInfo>? = null
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class SsoServerListInfo(
|
||||
@SerialId(1) val sIP: String = "",
|
||||
@SerialId(2) val iPort: Int,
|
||||
@SerialId(3) val linkType: Byte,
|
||||
@SerialId(4) val proxy: Byte,
|
||||
@SerialId(5) val protocolType: Byte? = null,
|
||||
@SerialId(6) val iTimeOut: Int? = 10
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class TimeStamp(
|
||||
@SerialId(1) val year: Int,
|
||||
@SerialId(2) val month: Byte,
|
||||
@SerialId(3) val day: Byte,
|
||||
@SerialId(4) val hour: Byte
|
||||
) : JceStruct
|
@ -1,7 +1,5 @@
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.data.jce
|
||||
|
||||
import kotlinx.atomicfu.AtomicInt
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.serialization.SerialId
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.qqandroid.io.JceStruct
|
||||
@ -14,20 +12,14 @@ internal class RequestPacket(
|
||||
@SerialId(1) val iVersion: Short = 3,
|
||||
@SerialId(2) val cPacketType: Byte = 0,
|
||||
@SerialId(3) val iMessageType: Int = 0,
|
||||
@SerialId(4) val iRequestId: Int = nextRequestPacketRequestId(),
|
||||
@SerialId(4) val iRequestId: Int,
|
||||
@SerialId(5) val sServantName: String = "",
|
||||
@SerialId(6) val sFuncName: String = "",
|
||||
@SerialId(7) val sBuffer: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(8) val iTimeout: Int = 0,
|
||||
@SerialId(9) val context: Map<String, String> = EMPTY_MAP,
|
||||
@SerialId(10) val status: Map<String, String> = EMPTY_MAP
|
||||
) : JceStruct {
|
||||
|
||||
}
|
||||
|
||||
private val requestPacketRequestId: AtomicInt = atomic(1921334513)
|
||||
internal fun nextRequestPacketRequestId(): Int = requestPacketRequestId.getAndAdd(2)
|
||||
|
||||
) : JceStruct
|
||||
|
||||
@Serializable
|
||||
internal class RequestDataVersion3(
|
||||
|
@ -18,7 +18,7 @@ internal class MsgSvc : ProtoBuf {
|
||||
@SerialId(1) val result: Int = 0,
|
||||
@SerialId(2) val errmsg: String = "",
|
||||
@SerialId(3) val syncCookie: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(4) val syncFlag: Int /* enum */ = 0,
|
||||
@SerialId(4) val syncFlag: SyncFlag,
|
||||
@SerialId(5) val uinPairMsgs: List<MsgComm.UinPairMsg>? = null,
|
||||
@SerialId(6) val bindUin: Long = 0L,
|
||||
@SerialId(7) val msgRspType: Int = 0,
|
||||
@ -147,9 +147,15 @@ internal class MsgSvc : ProtoBuf {
|
||||
@SerialId(2) val groupWithDraw: List<PbGroupMsgWithDrawReq>? = null
|
||||
) : ProtoBuf
|
||||
|
||||
internal enum class SyncFlag {
|
||||
START,
|
||||
CONTINUE,
|
||||
STOP
|
||||
}
|
||||
|
||||
@Serializable
|
||||
internal class PbGetMsgReq(
|
||||
@SerialId(1) val syncFlag: Int /* enum */ = 0,
|
||||
@SerialId(1) val syncFlag: SyncFlag,
|
||||
@SerialId(2) val syncCookie: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(3) val rambleFlag: Int = 1,
|
||||
@SerialId(4) val latestRambleNumber: Int = 20,
|
||||
|
@ -3,14 +3,33 @@ package net.mamoe.mirai.qqandroid.network.protocol.data.proto
|
||||
import kotlinx.serialization.SerialId
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.qqandroid.io.ProtoBuf
|
||||
import kotlin.random.Random
|
||||
|
||||
@Serializable
|
||||
class SyncCookie(
|
||||
@SerialId(2) val time: Long,
|
||||
@SerialId(3) val unknown1: Long = 2994099792,
|
||||
@SerialId(4) val unknown2: Long = 3497826378,
|
||||
@SerialId(5) val const1: Long = 1680172298,
|
||||
@SerialId(6) val const2: Long = 2424173273,
|
||||
@SerialId(7) val unknown3: Long = 0,
|
||||
@SerialId(8) val unknown4: Long = 0
|
||||
) : ProtoBuf
|
||||
@SerialId(1) val time1: Long? = null, // 1580277992
|
||||
@SerialId(2) val time: Long, // 1580277992
|
||||
@SerialId(3) val unknown1: Long = Random.nextLong(),// 678328038
|
||||
@SerialId(4) val unknown2: Long = Random.nextLong(), // 1687142153
|
||||
@SerialId(5) val const1: Long = Random.nextLong(), // 1458467940
|
||||
@SerialId(11) val const2: Long = Random.nextLong(), // 2683038258
|
||||
@SerialId(12) val unknown3: Long = 0x1d,
|
||||
@SerialId(13) val lastSyncTime: Long? = null,
|
||||
@SerialId(14) val unknown4: Long = 0
|
||||
) : ProtoBuf
|
||||
|
||||
/*
|
||||
|
||||
@Serializable
|
||||
class SyncCookie(
|
||||
@SerialId(1) val time1: Long? = null, // 1580277992
|
||||
@SerialId(2) val time: Long, // 1580277992
|
||||
@SerialId(3) val unknown1: Long = 678328038,// 678328038
|
||||
@SerialId(4) val unknown2: Long = 1687142153, // 1687142153
|
||||
@SerialId(5) val const1: Long = 1458467940, // 1458467940
|
||||
@SerialId(11) val const2: Long = 2683038258, // 2683038258
|
||||
@SerialId(12) val unknown3: Long = 0x1d,
|
||||
@SerialId(13) val lastSyncTime: Long? = null,
|
||||
@SerialId(14) val unknown4: Long = 0
|
||||
) : ProtoBuf
|
||||
*/
|
@ -87,9 +87,9 @@ internal inline fun PacketFactory<*>.buildOutgoingUniPacket(
|
||||
commandName: String = this.commandName,
|
||||
key: ByteArray = client.wLoginSigInfo.d2Key,
|
||||
extraData: ByteReadPacket = BRP_STUB,
|
||||
sequenceId: Int = client.nextSsoSequenceId(),
|
||||
body: BytePacketBuilder.(sequenceId: Int) -> Unit
|
||||
): OutgoingPacket {
|
||||
val sequenceId: Int = client.nextSsoSequenceId()
|
||||
|
||||
return OutgoingPacket(name, commandName, sequenceId, buildPacket {
|
||||
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
||||
|
@ -10,6 +10,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
|
||||
import net.mamoe.mirai.utils.DefaultLogger
|
||||
@ -67,7 +68,8 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
||||
MessageSvc.PushForceOffline,
|
||||
MessageSvc.PbSendMsg,
|
||||
FriendList.GetFriendGroupList,
|
||||
FriendList.GetTroopListSimplify
|
||||
FriendList.GetTroopListSimplify,
|
||||
ConfigPushSvc.PushReq
|
||||
) {
|
||||
// SvcReqMSFLoginNotify 自己的其他设备上限
|
||||
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
|
||||
@ -194,11 +196,14 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
||||
PacketLogger.verbose("sequenceId = $ssoSequenceId")
|
||||
check(readInt() == 0)
|
||||
val extraData = readBytes(readInt() - 4)
|
||||
PacketLogger.verbose("sso(inner)extraData = ${extraData.toUHexString()}")
|
||||
PacketLogger.verbose("(sso/inner)extraData = ${extraData.toUHexString()}")
|
||||
|
||||
commandName = readString(readInt() - 4)
|
||||
bot.client.outgoingPacketUnknownValue = readBytes(readInt() - 4)
|
||||
|
||||
if (commandName == "ConfigPushSvc.PushReq") {
|
||||
bot.client.configPushSvcPushReqSequenceId = ssoSequenceId
|
||||
}
|
||||
dataCompressed = readInt()
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,11 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
|
||||
import net.mamoe.mirai.qqandroid.utils.toMessageChain
|
||||
import net.mamoe.mirai.qqandroid.utils.toRichTextElems
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.cryptor.contentToString
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.io.hexToBytes
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -43,7 +45,7 @@ internal class MessageSvc {
|
||||
|
||||
override suspend fun QQAndroidBot.handle(packet: RequestPushNotify) {
|
||||
network.run {
|
||||
PbGetMsg(client, packet.stMsgInfo?.uMsgTime ?: 0).sendAndExpect<MultiPacket<FriendMessage>>()
|
||||
PbGetMsg(client, MsgSvc.SyncFlag.START, packet.stMsgInfo?.uMsgTime ?: 0).sendAndExpect<MultiPacket<FriendMessage>>()
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,17 +55,19 @@ internal class MessageSvc {
|
||||
/**
|
||||
* 获取好友消息和消息记录
|
||||
*/
|
||||
internal object PbGetMsg : PacketFactory<MultiPacket<FriendMessage>>("MessageSvc.PbGetMsg") {
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
internal object PbGetMsg : PacketFactory<PbGetMsg.Response>("MessageSvc.PbGetMsg") {
|
||||
val EXTRA_DATA =
|
||||
"08 00 12 33 6D 6F 64 65 6C 3A 78 69 61 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D".hexToBytes()
|
||||
"08 00 12 33 6D 6F 64 65 6C 3A 78 69 67 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D".hexToBytes()
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
syncFlag: MsgSvc.SyncFlag = MsgSvc.SyncFlag.START,
|
||||
msgTime: Long //PbPushMsg.msg.msgHead.msgTime
|
||||
): OutgoingPacket = buildOutgoingUniPacket(
|
||||
client//,
|
||||
// extraData = EXTRA_DATA.toReadPacket()
|
||||
client
|
||||
) {
|
||||
println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
|
||||
writeProtoBuf(
|
||||
MsgSvc.PbGetMsgReq.serializer(),
|
||||
MsgSvc.PbGetMsgReq(
|
||||
@ -74,10 +78,10 @@ internal class MessageSvc {
|
||||
otherRambleNumber = 3,
|
||||
onlineSyncFlag = 1,
|
||||
whisperSessionId = 0,
|
||||
syncFlag = syncFlag,
|
||||
// serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY,
|
||||
syncCookie = client.c2cMessageSync.syncCookie
|
||||
?: SyncCookie(msgTime).toByteArray(SyncCookie.serializer()).also { client.c2cMessageSync.syncCookie = it },
|
||||
syncFlag = 1
|
||||
?: SyncCookie(time = Random.nextLong()).toByteArray(SyncCookie.serializer())//.also { client.c2cMessageSync.syncCookie = it },
|
||||
// syncFlag = client.c2cMessageSync.syncFlag,
|
||||
//msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf,
|
||||
//pubaccountCookie = client.c2cMessageSync.pubAccountCookie
|
||||
@ -85,25 +89,40 @@ internal class MessageSvc {
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): MultiPacket<FriendMessage> {
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
internal class GetMsgSuccess(delegate: MutableList<FriendMessage>) : Response(MsgSvc.SyncFlag.STOP, delegate)
|
||||
|
||||
/**
|
||||
* 不要直接 expect 这个 class. 它可能
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
open class Response(internal val syncFlagFromServer: MsgSvc.SyncFlag, delegate: MutableList<FriendMessage>) : MultiPacket<FriendMessage>(delegate) {
|
||||
override fun toString(): String {
|
||||
return "MessageSvc.PbGetMsg.Response($syncFlagFromServer=$syncFlagFromServer, messages=List(size=${this.size}))"
|
||||
}
|
||||
}
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
|
||||
// 00 00 01 0F 08 00 12 00 1A 34 08 FF C1 C4 F1 05 10 FF C1 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 8A CA 91 D1 0C 48 9B A5 BD 9B 0A 58 DE 9D 99 F8 08 60 1D 68 FF C1 C4 F1 05 70 00 20 02 2A 9D 01 08 F3 C1 C4 F1 05 10 A2 FF 8C F0 03 18 01 22 8A 01 0A 2A 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 A6 01 20 0B 28 AE F9 01 30 F4 C1 C4 F1 05 38 A7 E3 D8 D4 84 80 80 80 01 B8 01 CD B5 01 12 08 08 01 10 00 18 00 20 00 1A 52 0A 50 0A 27 08 00 10 F4 C1 C4 F1 05 18 A7 E3 D8 D4 04 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 08 0A 06 0A 04 4E 4D 53 4C 12 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 12 04 4A 02 08 00 30 01 2A 15 08 97 A2 C1 F1 05 10 95 A6 F5 E5 0C 18 01 30 01 40 01 48 81 01 2A 10 08 D3 F7 B5 F1 05 10 DD F1 92 B7 07 18 01 30 01 38 00 42 00 48 00
|
||||
discardExact(4)
|
||||
val resp = readProtoBuf(MsgSvc.PbGetMsgResp.serializer())
|
||||
|
||||
if (resp.result != 0) {
|
||||
return MultiPacket(emptyList())
|
||||
println("!!! Result=${resp.result} !!!: " + resp.contentToString())
|
||||
return GetMsgSuccess(mutableListOf())
|
||||
}
|
||||
|
||||
bot.client.c2cMessageSync.syncCookie = resp.syncCookie
|
||||
bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie
|
||||
bot.client.c2cMessageSync.syncFlag = resp.syncFlag
|
||||
bot.client.c2cMessageSync.msgCtrlBuf = resp.msgCtrlBuf
|
||||
println(resp.contentToString())
|
||||
|
||||
if (resp.uinPairMsgs == null) {
|
||||
return MultiPacket(emptyList())
|
||||
return GetMsgSuccess(mutableListOf())
|
||||
}
|
||||
return MultiPacket(resp.uinPairMsgs.asSequence().flatMap { it.msg.asSequence() }.mapNotNull {
|
||||
|
||||
val messages = resp.uinPairMsgs.asSequence().flatMap { it.msg.asSequence() }.mapNotNull {
|
||||
when (it.msgHead.msgType) {
|
||||
166 -> {
|
||||
FriendMessage(
|
||||
@ -115,10 +134,29 @@ internal class MessageSvc {
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}.toList())
|
||||
}.toMutableList()
|
||||
if (resp.syncFlag == MsgSvc.SyncFlag.STOP) {
|
||||
return GetMsgSuccess(messages)
|
||||
}
|
||||
return Response(resp.syncFlag, messages)
|
||||
}
|
||||
|
||||
override suspend fun QQAndroidBot.handle(packet: Response) {
|
||||
when (packet.syncFlagFromServer) {
|
||||
MsgSvc.SyncFlag.STOP,
|
||||
MsgSvc.SyncFlag.START -> return
|
||||
|
||||
MsgSvc.SyncFlag.CONTINUE -> {
|
||||
network.run {
|
||||
PbGetMsg(client, MsgSvc.SyncFlag.CONTINUE, currentTimeSeconds)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 被挤下线
|
||||
*/
|
||||
@ -165,7 +203,7 @@ internal class MessageSvc {
|
||||
msgSeq = client.atomicNextMessageSequenceId(),
|
||||
msgRand = Random.nextInt().absoluteValue,
|
||||
syncCookie = client.c2cMessageSync.syncCookie?.takeIf { it.isNotEmpty() }
|
||||
?: SyncCookie(currentTimeSeconds).toByteArray(SyncCookie.serializer())
|
||||
?: SyncCookie(time = currentTimeSeconds).toByteArray(SyncCookie.serializer())
|
||||
// msgVia = 1
|
||||
)
|
||||
)
|
||||
@ -192,9 +230,10 @@ internal class MessageSvc {
|
||||
elems = message.toRichTextElems()
|
||||
)
|
||||
),
|
||||
msgSeq = client.atomicNextMessageSequenceId(),
|
||||
msgRand = 123,
|
||||
syncCookie = client.c2cMessageSync.syncCookie?.takeIf { it.isNotEmpty() } ?: byteArrayOf()
|
||||
msgSeq = client.atomicNextMessageSequenceId()
|
||||
// msgRand = 123
|
||||
//syncCookie = client.c2cMessageSync.syncCookie?.takeIf { it.isNotEmpty() } ?:
|
||||
//SyncCookie(currentTimeSeconds, Random.nextLong().absoluteValue, Random.nextLong().absoluteValue).toByteArray(SyncCookie.serializer())
|
||||
// msgVia = 1
|
||||
)
|
||||
)
|
||||
|
@ -11,21 +11,12 @@ import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
|
||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.*
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListReq
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetFriendListResp
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.GetTroopListReqV2Simplify
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Vec0xd50
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList.GetFriendGroupList.decode
|
||||
import net.mamoe.mirai.utils.cryptor.contentToString
|
||||
import net.mamoe.mirai.utils.io.discardExact
|
||||
import net.mamoe.mirai.utils.io.readRemainingBytes
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
|
||||
|
||||
internal class FriendList {
|
||||
@ -48,6 +39,7 @@ internal class FriendList {
|
||||
sFuncName = "GetTroopMemberListReq",
|
||||
sServantName = "mqq.IMService.FriendListServiceServantObj",
|
||||
iVersion = 3,
|
||||
iRequestId = client.nextRequestPacketRequestId(),
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"GTML",
|
||||
GetTroopMemberListReq.serializer(),
|
||||
@ -98,7 +90,7 @@ internal class FriendList {
|
||||
iVersion = 3,
|
||||
cPacketType = 0x00,
|
||||
iMessageType = 0x00000,
|
||||
iRequestId = 1921334513,
|
||||
iRequestId = client.nextRequestPacketRequestId(),
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"GetTroopListReqV2Simplify",
|
||||
GetTroopListReqV2Simplify.serializer(),
|
||||
@ -109,6 +101,7 @@ internal class FriendList {
|
||||
shVersion = 7,
|
||||
dwCompanyId = 0,
|
||||
versionNum = 1,
|
||||
vecGroupInfo = listOf(),
|
||||
getLongGroupName = 1
|
||||
)
|
||||
)
|
||||
|
@ -0,0 +1,60 @@
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.packet.login
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.JceCharset
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushResp
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
|
||||
import net.mamoe.mirai.utils.cryptor.contentToString
|
||||
import net.mamoe.mirai.utils.io.debugPrintThis
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushReq as PushReqJceStruct
|
||||
|
||||
|
||||
internal class ConfigPushSvc {
|
||||
object PushReq : PacketFactory<PushReqJceStruct>("ConfigPushSvc.PushReq") {
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): PushReqJceStruct {
|
||||
discardExact(4)
|
||||
val pushReq = decodeUniPacket(PushReqJceStruct.serializer())
|
||||
println(pushReq.contentToString())
|
||||
return pushReq
|
||||
}
|
||||
|
||||
override suspend fun QQAndroidBot.handle(packet: PushReqJceStruct) {
|
||||
network.run {
|
||||
buildOutgoingUniPacket(
|
||||
client,
|
||||
sequenceId = client.configPushSvcPushReqSequenceId.also { println("configPushSvcPushReqSequenceId=${client.configPushSvcPushReqSequenceId}") },
|
||||
commandName = "ConfigPushSvc.PushResp",
|
||||
name = "ConfigPushSvc.PushResp"
|
||||
) {
|
||||
writeJceStruct(
|
||||
RequestPacket.serializer(),
|
||||
RequestPacket(
|
||||
iRequestId = 0,
|
||||
iVersion = 3,
|
||||
sServantName = "QQService.ConfigPushSvc.MainServant",
|
||||
sFuncName = "PushResp",
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"PushResp",
|
||||
PushResp.serializer(),
|
||||
PushResp(
|
||||
type = packet.type,
|
||||
seq = packet.seq,
|
||||
jcebuf = if (packet.type == 3) packet.jcebuf else null
|
||||
)
|
||||
)
|
||||
),
|
||||
charset = JceCharset.UTF8
|
||||
)
|
||||
writePacket(this.build().debugPrintThis())
|
||||
}.sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -59,6 +59,7 @@ internal class StatSvc {
|
||||
RequestPacket(
|
||||
sServantName = "PushService",
|
||||
sFuncName = "SvcReqRegister",
|
||||
iRequestId = 0,
|
||||
sBuffer = jceRequestSBuffer(
|
||||
"SvcReqRegister",
|
||||
SvcReqRegister.serializer(),
|
||||
|
@ -126,7 +126,7 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
|
||||
} else {
|
||||
//if (flag2 == 1) {
|
||||
val loginExtraData = readBytes(readInt() - 4)
|
||||
loginExtraData.debugPrint("loginExtraData")
|
||||
loginExtraData.debugPrintThis("loginExtraData")
|
||||
// } else {
|
||||
// this.debugPrint()
|
||||
// error("未知 flag2")
|
||||
@ -137,7 +137,7 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
|
||||
println("uin=" + readString(readInt() - 4))
|
||||
|
||||
println("// 解密 body")
|
||||
readRemainingBytes().tryDecrypt().toReadPacket().debugPrint("outer body decrypted").apply {
|
||||
readRemainingBytes().tryDecrypt().toReadPacket().debugPrintThis("outer body decrypted").apply {
|
||||
when (flag1) {
|
||||
0x0A -> decodeSso()
|
||||
0x0B -> decodeUni()
|
||||
@ -148,7 +148,7 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
|
||||
|
||||
2 -> {
|
||||
|
||||
this.debugPrint("Oicq Request").apply {
|
||||
this.debugPrintThis("Oicq Request").apply {
|
||||
/*
|
||||
byte 2 // head flag
|
||||
short 27 + 2 + remaining.length
|
||||
@ -259,7 +259,7 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
this.debugPrint("uni packet")
|
||||
this.debugPrintThis("uni packet")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -274,11 +274,8 @@ fun ByteReadPacket.decodeUni() {
|
||||
println("// 尝试解 Uni")
|
||||
println("// head")
|
||||
//return
|
||||
readBytes(readInt() - 4).debugPrint("head").toReadPacket().apply {
|
||||
readBytes(readInt() - 4).debugPrintThis("head").toReadPacket().apply {
|
||||
val commandName = readString(readInt() - 4).also { PacketLogger.warning("commandName=$it") }
|
||||
if(commandName.contains("GetTroopList")){
|
||||
println("!\n".repeat(100))
|
||||
}
|
||||
println(commandName)
|
||||
println(" unknown4Bytes=" + readBytes(readInt() - 4).toUHexString())
|
||||
// 00 00 00 1A 43 6F 6E 66 69 67 50 75 73 68 53 76 63 2E 50 75 73 68 52 65 73 70
|
||||
@ -286,7 +283,7 @@ fun ByteReadPacket.decodeUni() {
|
||||
// 00 00 00 04
|
||||
println(" extraData=" + readBytes(readInt() - 4).toUHexString())
|
||||
}
|
||||
readBytes(readInt() - 4).debugPrint("Real body").read {
|
||||
readBytes(readInt() - 4).debugPrintThis("Real body").read {
|
||||
// real body
|
||||
//10 03 2C 3C 4C 56 23 51 51 53 65 72 76 69 63 65 2E 43 6F 6E 66 69 67 50 75 73 68 53 76 63 2E 4D 61 69 6E 53 65 72 76 61 6E 74 66 08 50 75 73 68 52 65 73 70 7D 00 00 1A 08 00 01 06 08 50 75 73 68 52 65 73 70 1D 00 00 09 0A 10 01 22 14 DA 6E B1 0B 8C 98 0C A8 0C
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ fun main(){
|
||||
)
|
||||
File(
|
||||
"""
|
||||
E:\Projects\QQAndroidFF\app\src\main\java\friendlist\
|
||||
E:\Projects\QQAndroidFF\app\src\main\java\ConfigPush
|
||||
""".trimIndent()
|
||||
).listFiles()!!.forEach {
|
||||
try {
|
||||
|
@ -16,7 +16,7 @@ import net.mamoe.mirai.utils.cryptor.Decrypter
|
||||
import net.mamoe.mirai.utils.cryptor.DecrypterType
|
||||
import net.mamoe.mirai.utils.cryptor.readProtoMap
|
||||
import net.mamoe.mirai.utils.io.ByteArrayPool
|
||||
import net.mamoe.mirai.utils.io.debugPrint
|
||||
import net.mamoe.mirai.utils.io.debugPrintThis
|
||||
import net.mamoe.mirai.utils.io.read
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
|
||||
@ -50,7 +50,7 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
|
||||
val headLength = readInt()
|
||||
val protoLength = readInt()
|
||||
if (debuggingTag != null) {
|
||||
readBytes(headLength).debugPrint("$debuggingTag head")
|
||||
readBytes(headLength).debugPrintThis("$debuggingTag head")
|
||||
} else {
|
||||
discardExact(headLength)
|
||||
}
|
||||
@ -58,7 +58,7 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
|
||||
// println(ByteReadPacket(bytes).readProtoMap())
|
||||
|
||||
if (debuggingTag != null) {
|
||||
bytes.read { readProtoMap() }.toString().debugPrint("$debuggingTag proto")
|
||||
bytes.read { readProtoMap() }.toString().debugPrintThis("$debuggingTag proto")
|
||||
}
|
||||
|
||||
return ProtoBuf.load(deserializer, bytes)
|
||||
|
@ -15,7 +15,7 @@ import kotlinx.io.core.readAvailable
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.contact.GroupId
|
||||
import net.mamoe.mirai.utils.io.ByteArrayPool
|
||||
import net.mamoe.mirai.utils.io.debugPrint
|
||||
import net.mamoe.mirai.utils.io.debugPrintThis
|
||||
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@ -46,7 +46,7 @@ internal suspend inline fun HttpClient.postImage(
|
||||
|
||||
userAgent("QQClient")
|
||||
|
||||
buildString().debugPrint("URL")
|
||||
buildString().debugPrintThis("URL")
|
||||
}
|
||||
|
||||
body = object : OutgoingContent.WriteChannelContent() {
|
||||
|
@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.data.EventPacket
|
||||
import net.mamoe.mirai.utils.PacketVersion
|
||||
import net.mamoe.mirai.utils.io.debugPrint
|
||||
import net.mamoe.mirai.utils.io.debugPrintThis
|
||||
|
||||
|
||||
data class GroupFileUploadPacket(inline val xmlMessage: String) : EventPacket
|
||||
@ -14,7 +14,7 @@ data class GroupFileUploadPacket(inline val xmlMessage: String) : EventPacket
|
||||
@PacketVersion(date = "2019.7.1", timVersion = "2.3.2 (21173)")
|
||||
internal object GroupFileUploadEventFactory : KnownEventParserAndHandler<GroupFileUploadPacket>(0x002Du) {
|
||||
override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): GroupFileUploadPacket {
|
||||
this.debugPrint("GroupFileUploadPacket")
|
||||
this.debugPrintThis("GroupFileUploadPacket")
|
||||
return GroupFileUploadPacket("")
|
||||
/*
|
||||
discardExact(60)
|
||||
|
@ -3,8 +3,8 @@
|
||||
package net.mamoe.mirai.timpc.network.packet.login
|
||||
|
||||
import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.timpc.network.TIMProtocol
|
||||
import net.mamoe.mirai.timpc.network.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.PacketFactory
|
||||
@ -142,7 +142,7 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
}
|
||||
0x13u -> {
|
||||
CaptchaResponse.Transmission().apply {
|
||||
with(debugPrint("验证码包")) {
|
||||
with(debugPrintThis("验证码包")) {
|
||||
/*
|
||||
* 00 05 01 00 00 01 23
|
||||
* 00 40 A0 E9 2F 12 1D 2E B1 15 26 89 EB C3 F0 9A 0C 03 00 03 A0 F2 74 57 58 57 E9 7A 2B C7 52 5D BC D8 7B D5 A4 7C AD 33 85 85 39 88 D2 CE AD 68 36 2E F0 AE 19 E8 25 3A F7 3A AD BE 19 A9 E7 C4 B5 4C
|
||||
|
@ -5,11 +5,13 @@ package net.mamoe.mirai.data
|
||||
*/
|
||||
interface Packet
|
||||
|
||||
object NoPakcet : Packet
|
||||
|
||||
/**
|
||||
* PacketFactory 可以一次解析多个包出来. 它们将会被分别广播.
|
||||
*/
|
||||
class MultiPacket<P : Packet>(delegate: List<P>) : List<P> by delegate, Packet {
|
||||
open class MultiPacket<P : Packet>(internal val delegate: MutableList<P>) : List<P> by delegate, Packet {
|
||||
override fun toString(): String {
|
||||
return "MultiPacket<${this.firstOrNull()?.let { it::class.simpleName }?: "?"}>"
|
||||
return "MultiPacket<${this.firstOrNull()?.let { it::class.simpleName } ?: "?"}>"
|
||||
}
|
||||
}
|
@ -19,19 +19,19 @@ fun Throwable.logStacktrace(message: String? = null) = DebugLogger.error(message
|
||||
fun debugPrintln(any: Any?) = DebugLogger.debug(any)
|
||||
|
||||
@MiraiDebugAPI("Low efficiency.")
|
||||
fun String.debugPrint(name: String): String {
|
||||
fun String.debugPrintThis(name: String): String {
|
||||
DebugLogger.debug("$name=$this")
|
||||
return this
|
||||
}
|
||||
|
||||
@MiraiDebugAPI("Low efficiency.")
|
||||
fun ByteArray.debugPrint(name: String): ByteArray {
|
||||
fun ByteArray.debugPrintThis(name: String): ByteArray {
|
||||
DebugLogger.debug(name + "=" + this.toUHexString())
|
||||
return this
|
||||
}
|
||||
|
||||
@MiraiDebugAPI("Low efficiency.")
|
||||
fun IoBuffer.debugPrint(name: String): IoBuffer {
|
||||
fun IoBuffer.debugPrintThis(name: String): IoBuffer {
|
||||
ByteArrayPool.useInstance {
|
||||
val count = this.readAvailable(it)
|
||||
DebugLogger.debug(name + "=" + it.toUHexString(offset = 0, length = count))
|
||||
@ -54,7 +54,7 @@ fun Input.debugDiscardExact(n: Number, name: String = "") {
|
||||
}
|
||||
|
||||
@MiraiDebugAPI("Low efficiency.")
|
||||
fun ByteReadPacket.debugPrint(name: String = ""): ByteReadPacket {
|
||||
fun ByteReadPacket.debugPrintThis(name: String = ""): ByteReadPacket {
|
||||
ByteArrayPool.useInstance {
|
||||
val count = this.readAvailable(it)
|
||||
DebugLogger.debug("ByteReadPacket $name=" + it.toUHexString(offset = 0, length = count))
|
||||
|
Loading…
Reference in New Issue
Block a user