diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt index 70c182680..8e7784eb4 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt @@ -140,6 +140,7 @@ internal object KnownPacketFactories { MessageSvcPbSendMsg, MessageSvcPbDeleteMsg, MessageSvcPbGetRoamMsgReq, + MessageSvcPbGetGroupMsg, FriendList.GetFriendGroupList, FriendList.DelFriend, FriendList.GetTroopListSimplify, @@ -157,6 +158,7 @@ internal object KnownPacketFactories { TroopManagement.GroupOperation, TroopManagement.GetTroopConfig, TroopManagement.ModifyAdmin, + TroopManagement.GetGroupLastMsgSeq, // TroopManagement.GetGroupInfo, TroopManagement.EditGroupNametag, TroopManagement.Kick, diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt index 95316c6d1..1c6d6ea41 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/TroopManagement.kt @@ -464,4 +464,54 @@ internal class TroopManagement { } } + + internal object GetGroupLastMsgSeq : OutgoingPacketFactory("OidbSvc.0x88d_0") { + sealed class Response(val groupUin: Long, val seq: Long) : Packet { + object Failed : Response(-1, -1) { + override fun toString(): String { + return "TroopManagement.GetGroupLastMsgSeq.Failed" + } + } + + class Success(groupUin: Long, seq: Long) : Response(groupUin, seq) { + override fun toString(): String { + return "TroopManagement.GetGroupLastMsgSeq.Response(groupUin=${groupUin}, seq=${seq})" + } + } + } + + operator fun invoke( + client: QQAndroidClient, + groupUin: Long, + ) = buildOutgoingUniPacket(client) { + writeOidb( + 2189, + 0, + Oidb0x88d.ReqBody.serializer(), + Oidb0x88d.ReqBody( + appid = client.subAppId.toInt(), + stzreqgroupinfo = listOf( + Oidb0x88d.ReqGroupInfo( + groupCode = groupUin, + stgroupinfo = Oidb0x88d.GroupInfo(groupCurMsgSeq = 0) + ) + ) + ) + ) + } + + override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response { + val resp = readOidbRespCommon(Oidb0x88d.RspBody.serializer()) { it.stzrspgroupinfo } + .toResult("OidbSvc.0x88d_0") { it == 0 } + .getOrNull() ?: return Response.Failed + + check(resp.isNotEmpty()) { return Response.Failed } + + val group = resp.first() + val info = group.stgroupinfo ?: return Response.Failed + val seq = info.groupCurMsgSeq ?: return Response.Failed + + return Response.Success(group.groupCode, seq.toLong()) + } + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetGroupMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetGroupMsg.kt new file mode 100644 index 000000000..b5ab204ab --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetGroupMsg.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2022 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + +package net.mamoe.mirai.internal.network.protocol.packet.chat.receive + +import io.ktor.utils.io.core.* +import net.mamoe.mirai.internal.QQAndroidBot +import net.mamoe.mirai.internal.network.Packet +import net.mamoe.mirai.internal.network.QQAndroidClient +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.packet.OutgoingPacketFactory +import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket +import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf +import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf + +/* + * 获取群历史消息 + */ +internal object MessageSvcPbGetGroupMsg : OutgoingPacketFactory("MessageSvc.PbGetGroupMsg") { + sealed class Response : Packet + + class Failed( + val result: Int, + val errorMsg: String + ) : Response() + + class Success( + val msgElem: List, + val beginSequence: Long, + val endSequence: Long, + ) : Response() + + operator fun invoke( + client: QQAndroidClient, + groupUin: Long, + messageSequence: Long, + count: Int, + ) = buildOutgoingUniPacket(client) { + writeProtoBuf( + MsgSvc.PbGetGroupMsgReq.serializer(), + MsgSvc.PbGetGroupMsgReq( + groupCode = groupUin, + beginSeq = messageSequence - count + 1, + endSeq = messageSequence, + + ) + ) + } + + override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response { + val resp = readProtoBuf(MsgSvc.PbGetGroupMsgResp.serializer()) + return if (resp.result != 0) { + Failed(resp.result, resp.errmsg) + } else { + Success( + msgElem = resp.msg, + beginSequence = resp.returnBeginSeq, + endSequence = resp.returnEndSeq + ) + } + } +} \ No newline at end of file