Fix sequenceId for FriendMessage

This commit is contained in:
Him188 2020-02-24 10:26:27 +08:00
parent 4d79a699b2
commit 6cbc69cd68
5 changed files with 72 additions and 20 deletions

View File

@ -542,7 +542,7 @@ internal class GroupImpl(
if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent")
}
lateinit var source: MessageSvc.PbSendMsg.MessageSourceFromSend
lateinit var source: MessageSvc.PbSendMsg.MessageSourceFromSendGroup
bot.network.run {
val response: MessageSvc.PbSendMsg.Response = MessageSvc.PbSendMsg.ToGroup(
bot.client,

View File

@ -129,9 +129,15 @@ internal abstract class QQAndroidBotBase constructor(
source.ensureSequenceIdAvailable()
network.run {
val response: PbMessageSvc.PbMsgWithDraw.Response =
val response: PbMessageSvc.PbMsgWithDraw.Response = if (source.groupId == 0L) {
PbMessageSvc.PbMsgWithDraw.Friend(bot.client, source.senderId, source.sequenceId, source.messageRandom, source.time)
.sendAndExpect()
} else {
PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageRandom)
.sendAndExpect()
}
check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" }
}
}

View File

@ -71,6 +71,35 @@ internal class PbMessageSvc {
)
}
fun Friend(
client: QQAndroidClient,
toUin: Long,
messageSequenceId: Int, // 56639
messageRandom: Int, // 921878719
time: Long,
messageType: Int = 0
): OutgoingPacket = buildOutgoingUniPacket(client) {
writeProtoBuf(
MsgSvc.PbMsgWithDrawReq.serializer(),
MsgSvc.PbMsgWithDrawReq(
c2cWithDraw = listOf(
MsgSvc.PbC2CMsgWithDrawReq(
subCmd = 1,
msgInfo = listOf(
MsgSvc.PbC2CMsgWithDrawReq.MsgInfo(
fromUin = client.bot.uin,
toUin = toUin,
msgSeq = messageSequenceId,
msgUid = messageRandom.toLong() and 0xffffffff,
msgTime = time and 0xffffffff
)
)
)
)
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
val resp = readProtoBuf(MsgSvc.PbMsgWithDrawResp.serializer())
resp.groupWithDraw?.firstOrNull()?.let {

View File

@ -269,7 +269,28 @@ internal class MessageSvc {
}
}
internal class MessageSourceFromSend(
internal class MessageSourceFromSendFriend(
val messageRandom: Int,
override val time: Long,
override val senderId: Long,
override val groupId: Long,
val sequenceId: Int
) : MessageSource {
@UseExperimental(ExperimentalCoroutinesApi::class)
override val id: Long
get() = sequenceId.toLong().shl(32) or
messageRandom.toLong().and(0xFFFFFFFF)
override suspend fun ensureSequenceIdAvailable() {
// nothing to do
}
override fun toString(): String {
return ""
}
}
internal class MessageSourceFromSendGroup(
val messageRandom: Int,
override val time: Long,
override val senderId: Long,
@ -286,7 +307,7 @@ internal class MessageSvc {
@UseExperimental(MiraiExperimentalAPI::class)
fun startWaitingSequenceId(contact: Contact) {
sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int>(timeoutMillis = 3000) {
if (it.messageRandom == this@MessageSourceFromSend.messageRandom) {
if (it.messageRandom == this@MessageSourceFromSendGroup.messageRandom) {
it.sequenceId
} else null
}
@ -305,14 +326,14 @@ internal class MessageSvc {
client: QQAndroidClient,
toUin: Long,
message: MessageChain,
crossinline sourceCallback: (MessageSource) -> Unit
crossinline sourceCallback: (MessageSourceFromSendFriend) -> Unit
): OutgoingPacket {
val source = MessageSourceFromSend(
val source = MessageSourceFromSendFriend(
messageRandom = Random.nextInt().absoluteValue,
senderId = client.uin,
time = currentTimeSeconds + client.timeDifference,
groupId = 0//
// sourceMessage = message
groupId = 0,
sequenceId = client.atomicNextMessageSequenceId()
)
sourceCallback(source)
return ToFriend(client, toUin, message, source)
@ -326,7 +347,7 @@ internal class MessageSvc {
client: QQAndroidClient,
toUin: Long,
message: MessageChain,
source: MessageSourceFromSend
source: MessageSourceFromSendFriend
): OutgoingPacket = buildOutgoingUniPacket(client) {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
@ -340,7 +361,7 @@ internal class MessageSvc {
elems = message.toRichTextElems(false)
)
),
msgSeq = client.atomicNextMessageSequenceId(),
msgSeq = source.sequenceId,
msgRand = source.messageRandom,
syncCookie = SyncCookie(time = source.time).toByteArray(SyncCookie.serializer())
// msgVia = 1
@ -353,10 +374,10 @@ internal class MessageSvc {
client: QQAndroidClient,
groupCode: Long,
message: MessageChain,
sourceCallback: (MessageSourceFromSend) -> Unit
sourceCallback: (MessageSourceFromSendGroup) -> Unit
): OutgoingPacket {
val source = MessageSourceFromSend(
val source = MessageSourceFromSendGroup(
messageRandom = Random.nextInt().absoluteValue,
senderId = client.uin,
time = currentTimeSeconds + client.timeDifference,
@ -375,7 +396,7 @@ internal class MessageSvc {
client: QQAndroidClient,
groupCode: Long,
message: MessageChain,
source: MessageSourceFromSend
source: MessageSourceFromSendGroup
): OutgoingPacket = buildOutgoingUniPacket(client) {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())

View File

@ -78,13 +78,9 @@ open class MessageReceipt<C : Contact>(
fun recallIn(millis: Long): Job {
@Suppress("BooleanLiteralArgument")
if (_isRecalled.compareAndSet(false, true)) {
when (val contact = target) {
is Group -> {
return contact.bot.recallIn(source, millis)
}
is QQ -> {
TODO()
}
return when (val contact = target) {
is QQ,
is Group -> contact.bot.recallIn(source, millis)
else -> error("Unknown contact type")
}
} else error("message is already or planned to be recalled")