Remove legacy sendAndExpect to reduce code complexity to avoid compiler bugs, fix #2049

This commit is contained in:
Him188 2022-05-25 20:36:58 +01:00
parent 167a29e0d8
commit c3f94a66d6
No known key found for this signature in database
GPG Key ID: BA439CDDCF652375
35 changed files with 632 additions and 618 deletions

View File

@ -52,7 +52,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.PbMessageSvc
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.network.protocol.packet.summarycard.SummaryCard
import net.mamoe.mirai.internal.network.psKey
import net.mamoe.mirai.internal.network.sKey
@ -257,7 +256,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
override suspend fun getOnlineOtherClientsList(bot: Bot, mayIncludeSelf: Boolean): List<OtherClientInfo> {
bot.asQQAndroidBot()
val response = bot.network.run {
StatSvc.GetDevLoginInfo(bot.client).sendAndExpect()
bot.network.sendAndExpect(StatSvc.GetDevLoginInfo(bot.client))
}
fun SvcDevLoginInfo.toOtherClientInfo() = OtherClientInfo(
@ -352,7 +351,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
override suspend fun getRawGroupList(bot: Bot): Sequence<Long> {
bot.asQQAndroidBot()
return bot.network.run {
FriendList.GetTroopListSimplify(bot.client).sendAndExpect(retry = 2)
bot.network.sendAndExpect(FriendList.GetTroopListSimplify(bot.client))
}.groups.asSequence().map { it.groupUin.shl(32) and it.groupCode }
}
@ -362,44 +361,45 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
groupUin: Long,
groupCode: Long,
ownerId: Long
): Sequence<MemberInfo> =
bot.asQQAndroidBot().network.run {
var nextUin = 0L
var sequence = sequenceOf<MemberInfoImpl>()
while (true) {
val data = FriendList.GetTroopMemberList(
): Sequence<MemberInfo> {
var nextUin = 0L
var sequence = sequenceOf<MemberInfoImpl>()
while (true) {
val data = bot.asQQAndroidBot().network.sendAndExpect(
FriendList.GetTroopMemberList(
client = bot.client,
targetGroupUin = groupUin,
targetGroupCode = groupCode,
nextUin = nextUin
).sendAndExpect(retry = 3)
sequence += data.members.asSequence().map { troopMemberInfo ->
MemberInfoImpl(bot.client, troopMemberInfo, ownerId)
}
nextUin = data.nextUin
if (nextUin == 0L) {
break
}
), 5000, 3
)
sequence += data.members.asSequence().map { troopMemberInfo ->
MemberInfoImpl(bot.client, troopMemberInfo, ownerId)
}
nextUin = data.nextUin
if (nextUin == 0L) {
break
}
return sequence
}
return sequence
}
override suspend fun recallGroupMessageRaw(
bot: Bot,
groupCode: Long,
messageIds: IntArray,
messageInternalIds: IntArray,
): Boolean = bot.asQQAndroidBot().run {
val response = network.run {
): Boolean {
val response = bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
client,
bot.client,
groupCode,
messageIds,
messageInternalIds
).sendAndExpect()
}
), 5000, 2
)
response is PbMessageSvc.PbMsgWithDraw.Response.Success
return response is PbMessageSvc.PbMsgWithDraw.Response.Success
}
override suspend fun recallFriendMessageRaw(
@ -408,18 +408,18 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
messageIds: IntArray,
messageInternalIds: IntArray,
time: Int,
): Boolean = bot.asQQAndroidBot().run {
val response = network.run {
): Boolean {
val response = bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
client,
bot.client,
targetId,
messageIds,
messageInternalIds,
time,
).sendAndExpect()
}
), 5000, 2
)
response is PbMessageSvc.PbMsgWithDraw.Response.Success
return response is PbMessageSvc.PbMsgWithDraw.Response.Success
}
override suspend fun recallGroupTempMessageRaw(
@ -429,19 +429,19 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
messageIds: IntArray,
messageInternalIds: IntArray,
time: Int
): Boolean = bot.asQQAndroidBot().run {
val response = network.run {
): Boolean {
val response = bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupTempMessage(
client,
bot.client,
groupUin,
targetId,
messageIds,
messageInternalIds,
time,
).sendAndExpect()
}
), 5000, 2
)
response is PbMessageSvc.PbMsgWithDraw.Response.Success
return response is PbMessageSvc.PbMsgWithDraw.Response.Success
}
@Suppress("RemoveExplicitTypeArguments") // false positive
@ -474,81 +474,92 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
}
}
network.run {
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
bot.asQQAndroidBot().client,
group.id,
source.sequenceIds,
source.internalIds
).sendAndExpect()
}
), 5000, 2
)
}
is OnlineMessageSourceFromFriendImpl,
is OnlineMessageSourceToFriendImpl,
is OnlineMessageSourceFromStrangerImpl,
is OnlineMessageSourceToStrangerImpl,
-> network.run {
-> {
check(source.fromId == bot.id) {
"can only recall a message sent by bot"
}
PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
), 5000, 2
)
}
is OnlineMessageSourceFromTempImpl,
is OnlineMessageSourceToTempImpl
-> network.run {
-> {
check(source.fromId == bot.id) {
"can only recall a message sent by bot"
}
source as OnlineMessageSourceToTempImpl
PbMessageSvc.PbMsgWithDraw.createForGroupTempMessage(
bot.client,
(source.target.group as GroupImpl).uin,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupTempMessage(
bot.client,
(source.target.group as GroupImpl).uin,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
), 5000, 2
)
}
is OfflineMessageSource -> network.run {
is OfflineMessageSource -> {
when (source.kind) {
MessageSourceKind.FRIEND, MessageSourceKind.STRANGER -> {
check(source.fromId == bot.id) {
"can only recall a message sent by bot"
}
PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds,
source.time
), 5000, 2
)
}
MessageSourceKind.TEMP -> {
check(source.fromId == bot.id) {
"can only recall a message sent by bot"
}
PbMessageSvc.PbMsgWithDraw.createForGroupTempMessage(
bot.client,
source.targetId, // groupUin
source.targetId, // memberUin
source.sequenceIds,
source.internalIds,
source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupTempMessage(
bot.client,
source.targetId, // groupUin
source.targetId, // memberUin
source.sequenceIds,
source.internalIds,
source.time
), 5000, 2
)
}
MessageSourceKind.GROUP -> {
PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
bot.asQQAndroidBot().network.sendAndExpect(
PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
bot.client,
source.targetId,
source.sequenceIds,
source.internalIds
), 5000, 2
)
}
}
}
@ -648,20 +659,20 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
accept: Boolean,
blackList: Boolean
): Unit = bot.asQQAndroidBot().run {
network.apply {
network.sendWithoutExpect(
NewContact.SystemMsgNewFriend.Action(
bot.client,
eventId = eventId,
fromId = fromId,
accept = accept,
blackList = blackList
).sendWithoutExpect()
)
)
if (!accept) return@apply
if (!accept) return
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
bot.friends.delegate.add(newFriend(bot, FriendInfoImpl(fromId, fromNick, "")))
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
bot.friends.delegate.add(newFriend(bot, FriendInfoImpl(fromId, fromNick, "")))
}
override suspend fun solveBotInvitedJoinGroupRequestEvent(
@ -670,8 +681,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
invitorId: Long,
groupId: Long,
accept: Boolean
) = bot.asQQAndroidBot().run {
network.run {
) {
bot.asQQAndroidBot().network.sendWithoutExpect(
NewContact.SystemMsgNewGroup.Action(
bot.client,
eventId = eventId,
@ -679,8 +690,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
groupId = groupId,
isInvited = true,
accept = accept
).sendWithoutExpect()
}
)
)
}
override suspend fun solveMemberJoinRequestEvent(
@ -692,8 +703,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
accept: Boolean?,
blackList: Boolean,
message: String
) = bot.asQQAndroidBot().run {
network.run {
) {
bot.asQQAndroidBot().network.sendWithoutExpect(
NewContact.SystemMsgNewGroup.Action(
bot.client,
eventId = eventId,
@ -703,8 +714,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
accept = accept,
blackList = blackList,
message = message
).sendWithoutExpect()
}
)
)
// Add member in MsgOnlinePush.PbPushMsg
}
@ -715,10 +726,12 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
groupId: Long,
dstUin: Long
): String {
bot.asQQAndroidBot().network.run {
val response = PttStore.GroupPttDown(bot.client, groupId, dstUin, md5).sendAndExpect()
return "http://${response.strDomain}${response.downPara.decodeToString()}"
}
val response = bot.asQQAndroidBot().network.sendAndExpect(
PttStore.GroupPttDown(bot.client, groupId, dstUin, md5),
5000,
2
)
return "http://${response.strDomain}${response.downPara.decodeToString()}"
}
override suspend fun muteAnonymousMember(
@ -769,10 +782,11 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
}
override suspend fun queryProfile(bot: Bot, targetId: Long): UserProfile {
bot.asQQAndroidBot().network.apply {
return SummaryCard.ReqSummaryCard(bot.client, targetId)
.sendAndExpect()
}
return bot.asQQAndroidBot().network.sendAndExpect(
SummaryCard.ReqSummaryCard(bot.client, targetId),
5000, 2
)
}
override suspend fun sendNudge(bot: Bot, nudge: Nudge, receiver: Contact): Boolean {
@ -784,17 +798,21 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
bot.network.run {
return if (receiver is Group) {
receiver.checkIsGroupImpl()
NudgePacket.troopInvoke(
client = bot.client,
messageReceiverGroupCode = receiver.id,
nudgeTargetId = nudge.target.id,
).sendAndExpect<NudgePacket.Response>().success
bot.network.sendAndExpect(
NudgePacket.troopInvoke(
client = bot.client,
messageReceiverGroupCode = receiver.id,
nudgeTargetId = nudge.target.id,
)
).success
} else {
NudgePacket.friendInvoke(
client = bot.client,
messageReceiverUin = receiver.id,
nudgeTargetId = nudge.target.id,
).sendAndExpect<NudgePacket.Response>().success
bot.network.sendAndExpect(
NudgePacket.friendInvoke(
client = bot.client,
messageReceiverUin = receiver.id,
nudgeTargetId = nudge.target.id,
)
).success
}
}
}
@ -876,7 +894,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
resourceKind: ResourceKind,
): MsgTransmit.PbMultiMsgTransmit {
bot.asQQAndroidBot()
when (val resp = MultiMsg.ApplyDown(bot.client, 2, resourceId, 1).sendAndExpect(bot)) {
when (val resp = bot.network.sendAndExpect(MultiMsg.ApplyDown(bot.client, 2, resourceId, 1))) {
is MultiMsg.ApplyDown.Response.RequireDownload -> {
@Suppress("DEPRECATION", "DEPRECATION_ERROR")
val http = Mirai.Http

View File

@ -28,7 +28,6 @@ import net.mamoe.mirai.internal.network.highway.tryServersUpload
import net.mamoe.mirai.internal.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.AtomicIntSeq
import net.mamoe.mirai.internal.utils.C2CPkgMsgParsingCache
import net.mamoe.mirai.internal.utils.structureToString
@ -76,7 +75,7 @@ internal sealed class AbstractUser(
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
}
val imageInfo = runBIO { resource.calculateImageInfo() }
val resp = bot.network.run {
val resp = bot.network.sendAndExpect(
LongConn.OffPicUp(
bot.client,
Cmd0x352.TryUpImgReq(
@ -92,8 +91,8 @@ internal sealed class AbstractUser(
imgOriginal = true,
buildVer = bot.client.buildVer,
),
).sendAndExpect<LongConn.OffPicUp.Response>()
}
), 5000, 2
)
return when (resp) {
is LongConn.OffPicUp.Response.FileExists -> {
@ -141,16 +140,18 @@ internal sealed class AbstractUser(
)
}.recoverCatchingSuppressed {
// try upload as group image
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = id,
md5 = resource.md5,
size = resource.size,
picWidth = imageInfo.width,
picHeight = imageInfo.height,
picType = getIdByImageType(imageInfo.imageType),
).sendAndExpect(bot)
val response: ImgStore.GroupPicUp.Response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = id,
md5 = resource.md5,
size = resource.size,
picWidth = imageInfo.width,
picHeight = imageInfo.height,
picType = getIdByImageType(imageInfo.imageType),
)
)
when (response) {
is ImgStore.GroupPicUp.Response.Failed -> {

View File

@ -30,7 +30,6 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.audioCodec
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.message.MessageReceipt
@ -69,10 +68,8 @@ internal class FriendImpl(
check(bot.friends[id] != null) {
"Friend $id had already been deleted"
}
bot.network.run {
FriendList.DelFriend.invoke(bot.client, this@FriendImpl).sendAndExpect().also {
check(it.isSuccess) { "delete friend failed: ${it.resultCode}" }
}
bot.network.sendAndExpect(FriendList.DelFriend.invoke(bot.client, this@FriendImpl), 5000, 2).let {
check(it.isSuccess) { "delete friend failed: ${it.resultCode}" }
}
}
@ -120,7 +117,7 @@ internal class FriendImpl(
)
)
}.recoverCatchingSuppressed {
when (val resp = PttStore.GroupPttUp(bot.client, bot.id, id, res).sendAndExpect(bot)) {
when (val resp = bot.network.sendAndExpect(PttStore.GroupPttUp(bot.client, bot.id, id, res))) {
is PttStore.GroupPttUp.Response.RequireUpload -> {
tryServersUpload(
bot,

View File

@ -28,7 +28,6 @@ import net.mamoe.mirai.internal.contact.file.RemoteFilesImpl
import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
import net.mamoe.mirai.internal.message.*
import net.mamoe.mirai.internal.network.components.BdhSession
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.logger
import net.mamoe.mirai.internal.network.highway.ChannelKind
import net.mamoe.mirai.internal.network.highway.Highway
@ -43,7 +42,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.audioCodec
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.voiceCodec
import net.mamoe.mirai.internal.network.protocol.packet.list.ProfileService
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.GroupPkgMsgParsingCache
import net.mamoe.mirai.internal.utils.ImagePatcher
import net.mamoe.mirai.internal.utils.RemoteFileImpl
@ -151,15 +149,13 @@ internal class GroupImpl constructor(
if (!bot.groups.delegate.remove(this)) {
return false
}
bot.network.run {
val response: ProfileService.GroupMngReq.GroupMngReqResponse = ProfileService.GroupMngReq(
bot.client,
this@GroupImpl.id
).sendAndExpect()
check(response.errorCode == 0) {
"Group.quit failed: $response".also {
bot.groups.delegate.add(this@GroupImpl)
}
val response: ProfileService.GroupMngReq.GroupMngReqResponse = bot.network.sendAndExpect(
ProfileService.GroupMngReq(bot.client, this@GroupImpl.id), 5000, 2
)
check(response.errorCode == 0) {
"Group.quit failed: $response".also {
bot.groups.delegate.add(this@GroupImpl)
}
}
BotLeaveEvent.Active(this).broadcast()
@ -210,8 +206,9 @@ internal class GroupImpl constructor(
}
val imageInfo = runBIO { resource.calculateImageInfo() }
bot.network.run<NetworkHandler, Image> {
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
val response: ImgStore.GroupPicUp.Response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = id,
@ -222,60 +219,60 @@ internal class GroupImpl constructor(
picHeight = imageInfo.height,
picType = getIdByImageType(imageInfo.imageType),
originalPic = 1
).sendAndExpect()
), 5000, 2
)
when (response) {
is ImgStore.GroupPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this@GroupImpl, resource, response.resultCode, response.message).broadcast()
if (response.message == "over file size max") throw OverFileSizeMaxException()
error("upload group image failed with reason ${response.message}")
}
is ImgStore.GroupPicUp.Response.FileExists -> {
val resourceId = resource.calculateResourceId()
return response.fileInfo.run {
OfflineGroupImage(
imageId = resourceId,
height = fileHeight,
width = fileWidth,
imageType = getImageTypeById(fileType),
size = resource.size
)
}
.also {
it.fileId = response.fileId.toInt()
}
.also { it.putIntoCache() }
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
}
is ImgStore.GroupPicUp.Response.RequireUpload -> {
// val servers = response.uploadIpList.zip(response.uploadPortList)
Highway.uploadResourceBdh(
bot = bot,
resource = resource,
kind = GROUP_IMAGE,
commandId = 2,
initialTicket = response.uKey,
noBdhAwait = true,
fallbackSession = {
BdhSession(
EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY,
ssoAddresses = response.uploadIpList.zip(response.uploadPortList).toMutableSet(),
)
},
when (response) {
is ImgStore.GroupPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this@GroupImpl, resource, response.resultCode, response.message).broadcast()
if (response.message == "over file size max") throw OverFileSizeMaxException()
error("upload group image failed with reason ${response.message}")
}
is ImgStore.GroupPicUp.Response.FileExists -> {
val resourceId = resource.calculateResourceId()
return response.fileInfo.run {
OfflineGroupImage(
imageId = resourceId,
height = fileHeight,
width = fileWidth,
imageType = getImageTypeById(fileType),
size = resource.size
)
return imageInfo.run {
OfflineGroupImage(
imageId = resource.calculateResourceId(),
width = width,
height = height,
imageType = imageType,
size = resource.size
)
}.also { it.fileId = response.fileId.toInt() }
.also { it.putIntoCache() }
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
}
.also {
it.fileId = response.fileId.toInt()
}
.also { it.putIntoCache() }
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
}
is ImgStore.GroupPicUp.Response.RequireUpload -> {
// val servers = response.uploadIpList.zip(response.uploadPortList)
Highway.uploadResourceBdh(
bot = bot,
resource = resource,
kind = GROUP_IMAGE,
commandId = 2,
initialTicket = response.uKey,
noBdhAwait = true,
fallbackSession = {
BdhSession(
EMPTY_BYTE_ARRAY, EMPTY_BYTE_ARRAY,
ssoAddresses = response.uploadIpList.zip(response.uploadPortList).toMutableSet(),
)
},
)
return imageInfo.run {
OfflineGroupImage(
imageId = resource.calculateResourceId(),
width = width,
height = height,
imageType = imageType,
size = resource.size
)
}.also { it.fileId = response.fileId.toInt() }
.also { it.putIntoCache() }
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
}
}
}
@ -300,8 +297,8 @@ internal class GroupImpl constructor(
res.voiceCodec,
""
)
}
}
}
private suspend fun uploadAudioResource(resource: ExternalResource) {
kotlin.runCatching {
@ -314,7 +311,7 @@ internal class GroupImpl constructor(
.toByteArray(Cmd0x388.ReqBody.serializer()),
)
}.recoverCatchingSuppressed {
when (val resp = PttStore.GroupPttUp(bot.client, bot.id, id, resource).sendAndExpect(bot)) {
when (val resp = bot.network.sendAndExpect(PttStore.GroupPttUp(bot.client, bot.id, id, resource))) {
is PttStore.GroupPttUp.Response.RequireUpload -> {
tryServersUpload(
bot,
@ -354,14 +351,14 @@ internal class GroupImpl constructor(
override suspend fun setEssenceMessage(source: MessageSource): Boolean {
checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = bot.network.run {
val result = bot.network.sendAndExpect(
TroopEssenceMsgManager.SetEssence(
bot.client,
this@GroupImpl.uin,
source.internalIds.first(),
source.ids.first()
).sendAndExpect()
}
), 5000, 2
)
return result.success
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.contact
@ -24,7 +24,6 @@ import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement.GroupOperation
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement.SwitchAnonymousChat
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
@Suppress("SetterBackingFieldAssignment")
internal class GroupSettingsImpl(
@ -43,9 +42,7 @@ internal class GroupSettingsImpl(
val oldValue = getter()
setter(newValue)
launch {
bot.network.run {
packetConstructor(bot.client, id, newValue).sendWithoutExpect()
}
bot.network.sendWithoutExpect(packetConstructor(bot.client, id, newValue))
eventConstructor(oldValue).broadcast()
}
}
@ -98,7 +95,7 @@ internal class GroupSettingsImpl(
checkBotPermission(MemberPermission.ADMINISTRATOR)
launch {
//Handle it in NoticePipelineContext#processAllowAnonymousChat
SwitchAnonymousChat(bot.client, id, newValue).sendAndExpect(bot.network)
bot.network.sendAndExpect(SwitchAnonymousChat(bot.client, id, newValue))
}
}
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("EXPERIMENTAL_API_USAGE")
@ -93,13 +93,13 @@ internal class NormalMemberImpl constructor(
val oldValue = _nameCard
_nameCard = newValue
launch {
bot.network.run {
bot.network.sendWithoutExpect(
TroopManagement.EditGroupNametag(
bot.client,
this@NormalMemberImpl,
newValue,
).sendWithoutExpect()
}
)
)
MemberCardChangeEvent(oldValue, newValue, this@NormalMemberImpl).broadcast()
}
}
@ -113,13 +113,13 @@ internal class NormalMemberImpl constructor(
val oldValue = _specialTitle
_specialTitle = newValue
launch {
bot.network.run {
bot.network.sendWithoutExpect(
TroopManagement.EditSpecialTitle(
bot.client,
this@NormalMemberImpl,
newValue,
).sendWithoutExpect()
}
)
)
MemberSpecialTitleChangeEvent(oldValue, newValue, this@NormalMemberImpl, null).broadcast()
}
}
@ -133,14 +133,14 @@ internal class NormalMemberImpl constructor(
"durationSeconds must greater than zero"
}
checkBotPermissionHigherThanThis("mute")
bot.network.run {
bot.network.sendAndExpect(
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@NormalMemberImpl.id,
timeInSecond = durationSeconds,
).sendAndExpect<TroopManagement.Mute.Response>()
}
), 5000, 2
)
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
(net.mamoe.mirai.event.events.MemberMuteEvent(this@NormalMemberImpl, durationSeconds, null).broadcast())
@ -149,14 +149,14 @@ internal class NormalMemberImpl constructor(
override suspend fun unmute() {
checkBotPermissionHigherThanThis("unmute")
bot.network.run {
bot.network.sendAndExpect(
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@NormalMemberImpl.id,
timeInSecond = 0,
).sendAndExpect<TroopManagement.Mute.Response>()
}
), 5000, 2
)
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
(net.mamoe.mirai.event.events.MemberUnmuteEvent(this@NormalMemberImpl, null).broadcast())
@ -168,25 +168,25 @@ internal class NormalMemberImpl constructor(
check(group.members[this.id] != null) {
"Member ${this.id} had already been kicked from group ${group.id}"
}
bot.network.run {
val response: TroopManagement.Kick.Response = TroopManagement.Kick(
val response: TroopManagement.Kick.Response = bot.network.sendAndExpect(
TroopManagement.Kick(
client = bot.client,
groupCode = group.groupCode,
memberId = id,
message = message,
ban = block
).sendAndExpect()
), 5000, 2
)
// Note: when member not found, result is still true.
// Note: when member not found, result is still true.
if (response.ret == 255) error("Operation too fast") // https://github.com/mamoe/mirai/issues/1503
check(response.success) { "kick failed: ${response.ret}" }
if (response.ret == 255) error("Operation too fast") // https://github.com/mamoe/mirai/issues/1503
check(response.success) { "kick failed: ${response.ret}" }
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
group.members.delegate.removeIf { it.id == this@NormalMemberImpl.id }
this@NormalMemberImpl.cancel(CancellationException("Kicked by bot"))
MemberLeaveEvent.Kick(this@NormalMemberImpl, null).broadcast()
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
group.members.delegate.removeIf { it.id == this@NormalMemberImpl.id }
this@NormalMemberImpl.cancel(CancellationException("Kicked by bot"))
MemberLeaveEvent.Kick(this@NormalMemberImpl, null).broadcast()
}
override suspend fun modifyAdmin(operation: Boolean) {
@ -201,21 +201,21 @@ internal class NormalMemberImpl constructor(
if (origin == new) return
bot.network.run {
val resp: TroopManagement.ModifyAdmin.Response = TroopManagement.ModifyAdmin(
val resp: TroopManagement.ModifyAdmin.Response = bot.network.sendAndExpect(
TroopManagement.ModifyAdmin(
client = bot.client,
member = this@NormalMemberImpl,
operation = operation,
).sendAndExpect()
), 5000, 2
) as TroopManagement.ModifyAdmin.Response
check(resp.success) {
"Failed to modify admin, cause: ${resp.msg}"
}
this@NormalMemberImpl.permission = new
MemberPermissionChangeEvent(this@NormalMemberImpl, origin, new).broadcast()
check(resp.success) {
"Failed to modify admin, cause: ${resp.msg}"
}
this@NormalMemberImpl.permission = new
MemberPermissionChangeEvent(this@NormalMemberImpl, origin, new).broadcast()
}
}

View File

@ -138,7 +138,7 @@ internal abstract class SendMessageHandler<C : Contact> {
fragmented = step == SendMessageStep.FRAGMENTED
) { source = it }.forEach { packet ->
when (val resp = packet.sendAndExpect<Packet>()) {
when (val resp = bot.network.sendAndExpect<Packet>(packet, 5000, 2)) {
is MessageSvcPbSendMsg.Response -> {
if (resp is MessageSvcPbSendMsg.Response.MessageTooLarge) {
return when (step) {

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:OptIn(LowLevelApi::class)
@file:Suppress(
@ -54,11 +54,8 @@ internal class StrangerImpl(
check(bot.strangers[this.id] != null) {
"Stranger ${this.id} had already been deleted"
}
bot.network.run {
StrangerList.DelStranger(bot.client, this@StrangerImpl)
.sendAndExpect().also {
check(it.isSuccess) { "delete Stranger failed: ${it.result}" }
}
bot.network.sendAndExpect(StrangerList.DelStranger(bot.client, this@StrangerImpl), 5000, 2).also {
check(it.isSuccess) { "delete Stranger failed: ${it.result}" }
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -15,7 +15,6 @@ import net.mamoe.mirai.contact.file.AbsoluteFolder
import net.mamoe.mirai.internal.message.FileMessageImpl
import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.toResult
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.message.data.FileMessage
import net.mamoe.mirai.utils.toUHexString
@ -59,13 +58,14 @@ internal class AbsoluteFileImpl(
}
override suspend fun exists(): Boolean {
return FileManagement.GetFileInfo(
client,
groupCode = contact.id,
busId = busId,
fileId = id
).sendAndExpect(bot)
.toResult("AbsoluteFileImpl.exists", checkResp = false)
return bot.network.sendAndExpect(
FileManagement.GetFileInfo(
client,
groupCode = contact.id,
busId = busId,
fileId = id
)
).toResult("AbsoluteFileImpl.exists", checkResp = false)
.getOrThrow()
.fileInfo != null
}
@ -78,9 +78,20 @@ internal class AbsoluteFileImpl(
if (folder.absolutePath == this.parentOrRoot.absolutePath) return true
checkPermission("moveTo")
val result = FileManagement.MoveFile(client, contact.id, busId, id, parent.idOrRoot, folder.idOrRoot)
.sendAndExpect(bot).toResult("AbsoluteFileImpl.moveTo", checkResp = false)
.getOrThrow()
val result =
bot.network.sendAndExpect(
FileManagement.MoveFile(
client,
contact.id,
busId,
id,
parent.idOrRoot,
folder.idOrRoot
)
)
.toResult("AbsoluteFileImpl.moveTo", checkResp = false)
.getOrThrow()
return when (result.int32RetCode) {
-36 -> throwPermissionDeniedException("moveTo")
@ -103,14 +114,14 @@ internal class AbsoluteFileImpl(
// java.lang.IllegalStateException: Failed AbsoluteFileImpl.getUrl, result=-303, msg=param error: bus_id
// java.lang.IllegalStateException: Failed AbsoluteFileImpl.getUrl, result=-103, msg=GetFileAttrAction file not exist
val resp = FileManagement.RequestDownload(
client,
groupCode = contact.id,
busId = busId,
fileId = id
).sendAndExpect(bot)
.toResult("AbsoluteFileImpl.getUrl")
.getOrElse { return null }
val resp = bot.network.sendAndExpect(
FileManagement.RequestDownload(
client,
groupCode = contact.id,
busId = busId,
fileId = id
)
).toResult("AbsoluteFileImpl.getUrl").getOrElse { return null }
return "http://${resp.downloadIp}/ftn_handler/${resp.downloadUrl.toUHexString("")}/?fname=" +
@ -133,8 +144,7 @@ internal class AbsoluteFileImpl(
override fun toString(): String = "AbsoluteFile(name=$name, absolutePath=$absolutePath, id=$id)"
override suspend fun refreshed(): AbsoluteFile? {
val result = FileManagement.GetFileInfo(client, contact.id, id, busId)
.sendAndExpect(bot)
val result = bot.network.sendAndExpect(FileManagement.GetFileInfo(client, contact.id, id, busId))
.toResult("AbsoluteFile.refreshed")
.getOrNull()?.fileInfo
?: return null

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -27,7 +27,6 @@ import net.mamoe.mirai.internal.network.protocol
import net.mamoe.mirai.internal.network.protocol.data.proto.*
import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.toResult
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.FileSystem
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.utils.*
@ -113,12 +112,15 @@ internal class AbsoluteFolderImpl(
return flow {
var index = 0
while (true) {
val list = FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = folderId,
startIndex = index
).sendAndExpect(client.bot).toResult("AbsoluteFolderImpl.getFilesFlow").getOrThrow()
val list =
client.bot.network.sendAndExpect(
FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = folderId,
startIndex = index
)
).toResult("AbsoluteFolderImpl.getFilesFlow").getOrThrow()
index += list.itemList.size
if (list.int32RetCode != 0) return@flow
@ -139,13 +141,16 @@ internal class AbsoluteFolderImpl(
// TODO: 12/10/2021 checkPermission for AbsoluteFolderImpl.upload
content.withAutoClose {
val resp = FileManagement.RequestUpload(
folder.client,
groupCode = folder.contact.id,
folderId = folder.id,
resource = content,
filename = filepath
).sendAndExpect(folder.bot).toResult("AbsoluteFolderImpl.upload").getOrThrow()
val resp =
folder.bot.network.sendAndExpect(
FileManagement.RequestUpload(
folder.client,
groupCode = folder.contact.id,
folderId = folder.id,
resource = content,
filename = filepath
)
).toResult("AbsoluteFolderImpl.upload").getOrThrow()
when (resp.int32RetCode) {
-36 -> folder.throwPermissionDeniedException("uploadNewFile")
@ -254,12 +259,14 @@ internal class AbsoluteFolderImpl(
var index = 0
while (true) {
val list = runBlocking {
FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = id,
startIndex = index
).sendAndExpect(bot)
bot.network.sendAndExpect(
FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = id,
startIndex = index
)
)
}.toResult("AbsoluteFolderImpl.getFilesFlow").getOrThrow()
index += list.itemList.size
@ -307,8 +314,8 @@ internal class AbsoluteFolderImpl(
// server only support nesting depth level of 1 so we don't need to check the name
val result = FileManagement.CreateFolder(client, contact.id, this.id, name)
.sendAndExpect(bot).toResult("AbsoluteFolderImpl.mkdir", checkResp = false)
val result = bot.network.sendAndExpect(FileManagement.CreateFolder(client, contact.id, this.id, name))
.toResult("AbsoluteFolderImpl.mkdir", checkResp = false)
.getOrThrow() // throw protocol errors
/*
@ -389,7 +396,7 @@ internal class AbsoluteFolderImpl(
if (!deep) return null
return folders().map { it.resolveFileById(id, deep) }.firstOrNull{ it != null }
return folders().map { it.resolveFileById(id, deep) }.firstOrNull { it != null }
}
override suspend fun resolveFiles(path: String): Flow<AbsoluteFile> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -19,7 +19,6 @@ import net.mamoe.mirai.contact.file.AbsoluteFolder
import net.mamoe.mirai.internal.asQQAndroidBot
import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.toResult
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.FileSystem
import net.mamoe.mirai.utils.cast
@ -72,11 +71,13 @@ internal abstract class AbstractAbsoluteFileFolder(
parentOrFail()
checkPermission("renameTo")
val result = if (isFile) {
FileManagement.RenameFile(client, contact.id, busId, id, parent.idOrRoot, newName)
} else {
FileManagement.RenameFolder(client, contact.id, id, newName)
}.sendAndExpect(bot)
val result = bot.network.sendAndExpect(
if (isFile) {
FileManagement.RenameFile(client, contact.id, busId, id, parent.idOrRoot, newName)
} else {
FileManagement.RenameFolder(client, contact.id, id, newName)
}
)
result.toResult("AbstractAbsoluteFileFolder.renameTo") {
when (it) {
@ -95,10 +96,10 @@ internal abstract class AbstractAbsoluteFileFolder(
suspend fun delete(): Boolean {
checkPermission("delete")
val result = if (isFile) {
FileManagement.DeleteFile(client, contact.id, busId, id, parent.idOrRoot).sendAndExpect(bot)
bot.network.sendAndExpect(FileManagement.DeleteFile(client, contact.id, busId, id, parent.idOrRoot))
} else {
// natively 'recursive'
FileManagement.DeleteFolder(client, contact.id, id).sendAndExpect(bot)
bot.network.sendAndExpect(FileManagement.DeleteFolder(client, contact.id, id))
}.toResult("AbstractAbsoluteFileFolder.delete", checkResp = false).getOrThrow()
return when (result.int32RetCode) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -25,7 +25,6 @@ import net.mamoe.mirai.internal.contact.FriendImpl
import net.mamoe.mirai.internal.message.toMessageChainOnline
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetRoamMsgReq
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.utils.*
import java.util.stream.Stream
@ -123,15 +122,17 @@ internal class RoamingMessagesImplFriend(
lastMessageTime: Long,
random: Long
): MessageSvcPbGetRoamMsgReq.Response {
return MessageSvcPbGetRoamMsgReq.createForFriend(
client = contact.bot.client,
uin = contact.id,
timeStart = timeStart,
lastMsgTime = lastMessageTime,
random = random,
maxCount = 1000,
sig = byteArrayOf(),
pwd = byteArrayOf()
).sendAndExpect(contact.bot).value.check()
return contact.bot.network.sendAndExpect(
MessageSvcPbGetRoamMsgReq.createForFriend(
client = contact.bot.client,
uin = contact.id,
timeStart = timeStart,
lastMsgTime = lastMessageTime,
random = random,
maxCount = 1000,
sig = byteArrayOf(),
pwd = byteArrayOf()
)
).value.check()
}
}

View File

@ -28,7 +28,6 @@ import net.mamoe.mirai.internal.contact.file.resolved
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x6d8.GetFileListRspBody
import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.toResult
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.message.data.FileMessage
import net.mamoe.mirai.utils.cast
import kotlin.contracts.contract
@ -51,8 +50,8 @@ internal data class FileMessageImpl(
get() = busId
override suspend fun toAbsoluteFile(contact: FileSupported): AbsoluteFile? {
val result = FileManagement.GetFileInfo(contact.bot.asQQAndroidBot().client, contact.id, id, busId)
.sendAndExpect(contact.bot.asQQAndroidBot())
val result = contact.bot.asQQAndroidBot().network
.sendAndExpect(FileManagement.GetFileInfo(contact.bot.asQQAndroidBot().client, contact.id, id, busId))
.toResult("FileMessage.toAbsoluteFile").getOrThrow()
if (result.fileInfo == null) return null

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -18,7 +18,6 @@ import net.mamoe.mirai.internal.asQQAndroidBot
import net.mamoe.mirai.internal.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.ImagePatcher
import net.mamoe.mirai.internal.utils.ImagePatcher.Companion.withCache
import net.mamoe.mirai.message.data.Image
@ -66,18 +65,20 @@ internal class InternalImageProtocolImpl : InternalImageProtocol {
width: Int,
height: Int
): Boolean {
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = context.id,
md5 = md5,
size = size,
filename = "${md5.toUHexString("")}.${type.formatName}",
picWidth = width,
picHeight = height,
picType = getIdByImageType(type),
originalPic = 1
).sendAndExpect(bot)
val response: ImgStore.GroupPicUp.Response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = context.id,
md5 = md5,
size = size,
filename = "${md5.toUHexString("")}.${type.formatName}",
picWidth = width,
picHeight = height,
picType = getIdByImageType(type),
originalPic = 1
)
)
return response is ImgStore.GroupPicUp.Response.FileExists
}
@ -93,22 +94,24 @@ internal class InternalImageProtocolImpl : InternalImageProtocol {
width: Int,
height: Int
): Boolean {
val resp = LongConn.OffPicUp(
bot.client,
Cmd0x352.TryUpImgReq(
buType = 1,
srcUin = bot.id,
dstUin = context.id,
fileMd5 = md5,
fileSize = size,
imgWidth = width,
imgHeight = height,
imgType = getIdByImageType(type),
fileName = "${md5.toUHexString("")}.${type.formatName}",
imgOriginal = true,
buildVer = bot.client.buildVer,
),
).sendAndExpect<LongConn.OffPicUp.Response>(bot)
val resp = bot.network.sendAndExpect(
LongConn.OffPicUp(
bot.client,
Cmd0x352.TryUpImgReq(
buType = 1,
srcUin = bot.id,
dstUin = context.id,
fileMd5 = md5,
fileSize = size,
imgWidth = width,
imgHeight = height,
imgType = getIdByImageType(type),
fileName = "${md5.toUHexString("")}.${type.formatName}",
imgOriginal = true,
buildVer = bot.client.buildVer,
),
)
)
return resp is LongConn.OffPicUp.Response.FileExists
}
@ -124,18 +127,20 @@ internal class InternalImageProtocolImpl : InternalImageProtocol {
width: Int,
height: Int
): Boolean {
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = 1,
md5 = md5,
size = size,
filename = "${md5.toUHexString("")}.${type.formatName}",
picWidth = width,
picHeight = height,
picType = getIdByImageType(type),
originalPic = 1
).sendAndExpect(bot)
val response: ImgStore.GroupPicUp.Response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = 1,
md5 = md5,
size = size,
filename = "${md5.toUHexString("")}.${type.formatName}",
picWidth = width,
picHeight = height,
picType = getIdByImageType(type),
originalPic = 1
)
)
return response is ImgStore.GroupPicUp.Response.FileExists
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -194,14 +194,14 @@ internal open class MultiMsgUploader(
open suspend fun uploadAndReturnResId(): String {
val data = toMessageValidationData()
val response = client.bot.network.run {
val response = client.bot.network.sendAndExpect(
MultiMsg.ApplyUp.createForGroup(
buType = if (isLong) 1 else 2,
client = client,
messageData = data,
dstUin = handler.targetUin
).sendAndExpect()
}
), 5000, 2
)
val resId: String
when (response) {

View File

@ -28,7 +28,6 @@ import net.mamoe.mirai.internal.contact.info.GroupInfoImpl
import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl
import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.isValid
@ -39,7 +38,6 @@ import net.mamoe.mirai.internal.network.protocol.data.jce.isValid
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
import net.mamoe.mirai.internal.network.protocol.packet.list.StrangerList
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.info
import net.mamoe.mirai.utils.retryCatching
@ -140,9 +138,11 @@ internal class ContactUpdaterImpl(
var count = 0
var total: Short
while (true) {
val data = FriendList.GetFriendGroupList(
bot.client, count, 150, 0, 0
).sendAndExpect(bot, timeoutMillis = 5000, retry = 2)
val data = bot.network.sendAndExpect(
FriendList.GetFriendGroupList(bot.client, count, 150, 0, 0),
timeout = 5000,
attempts = 2
)
total = data.totalFriendCount
@ -163,9 +163,11 @@ internal class ContactUpdaterImpl(
logger.info { "Loaded ${list.size} friends from local cache." }
// For sync bot nick
FriendList.GetFriendGroupList(
bot.client, 0, 1, 0, 0
).sendAndExpect<Packet>(bot)
bot.network.sendAndExpect(
FriendList.GetFriendGroupList(
bot.client, 0, 1, 0, 0
)
)
list
} else {
@ -225,8 +227,12 @@ internal class ContactUpdaterImpl(
}
var currentCount = 0
logger.info { "Start loading stranger list..." }
val response = StrangerList.GetStrangerList(bot.client)
.sendAndExpect(bot, timeoutMillis = 5000, retry = 2)
val response = bot.network.sendAndExpect(
StrangerList.GetStrangerList(bot.client),
timeout = 5000,
attempts = 2
)
if (response.result == 0) {
response.strangerList.forEach {
@ -245,11 +251,12 @@ internal class ContactUpdaterImpl(
if (initGroupOk) {
return
}
TroopManagement.GetTroopConfig(bot.client).sendAndExpect(bot)
bot.network.sendAndExpect(TroopManagement.GetTroopConfig(bot.client))
logger.info { "Start loading group list..." }
val troopListData = FriendList.GetTroopListSimplify(bot.client)
.sendAndExpect(bot, retry = 5)
val troopListData = bot.network.sendAndExpect(FriendList.GetTroopListSimplify(bot.client), attempts = 5)
val semaphore = Semaphore(30)

View File

@ -15,7 +15,6 @@ import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.protocol.packet.login.Heartbeat
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
internal interface HeartbeatProcessor {
/**
@ -44,18 +43,18 @@ internal interface HeartbeatProcessor {
internal class HeartbeatProcessorImpl : HeartbeatProcessor {
override suspend fun doStatHeartbeatNow(networkHandler: NetworkHandler) {
StatSvc.SimpleGet(networkHandler.context.bot.client).sendAndExpect(
networkHandler,
timeoutMillis = networkHandler.context[SsoProcessorContext].configuration.heartbeatTimeoutMillis,
retry = 2
networkHandler.sendAndExpect(
StatSvc.SimpleGet(networkHandler.context.bot.client),
timeout = networkHandler.context[SsoProcessorContext].configuration.heartbeatTimeoutMillis,
attempts = 2
)
}
override suspend fun doAliveHeartbeatNow(networkHandler: NetworkHandler) {
Heartbeat.Alive(networkHandler.context.bot.client).sendAndExpect(
networkHandler,
timeoutMillis = networkHandler.context[SsoProcessorContext].configuration.heartbeatTimeoutMillis,
retry = 2
networkHandler.sendAndExpect(
Heartbeat.Alive(networkHandler.context.bot.client),
timeout = networkHandler.context[SsoProcessorContext].configuration.heartbeatTimeoutMillis,
attempts = 2
)
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.components
@ -13,7 +13,6 @@ import kotlinx.coroutines.*
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin15
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.network.LoginFailedException
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.info
@ -66,6 +65,6 @@ internal class KeyRefreshProcessorImpl(
}
override suspend fun refreshKeysNow(handler: NetworkHandler) {
WtLogin15(handler.context[SsoProcessor].client).sendAndExpect(handler)
handler.sendAndExpect(WtLogin15(handler.context[SsoProcessor].client))
}
}

View File

@ -18,7 +18,6 @@ import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbGetMsg
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.addNameHierarchically
import net.mamoe.mirai.utils.childScope
@ -64,7 +63,7 @@ internal class MessageSvcSyncerImpl(
it.bot == this@MessageSvcSyncerImpl.bot
}
}
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null).sendAndExpect(bot)
bot.network.sendAndExpect(MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null))
} ?: error("timeout syncing friend message history.")
logger.info { "Syncing friend message history: Success." }
}

View File

@ -26,7 +26,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin10
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin2
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin20
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin9
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.network.*
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import net.mamoe.mirai.utils.LoginSolver
@ -148,7 +147,9 @@ internal class SsoProcessorImpl(
}
private suspend fun registerClientOnline(handler: NetworkHandler): StatSvc.Register.Response {
return StatSvc.Register.online(client).sendAndExpect(handler).also { registerResp = it }
return handler.sendAndExpect(StatSvc.Register.online(client)).also {
registerResp = it
}
}
override suspend fun logout(handler: NetworkHandler) {
@ -179,7 +180,8 @@ internal class SsoProcessorImpl(
protected val bot get() = context.bot
protected val logger get() = bot.logger
protected suspend fun <R : Packet?> OutgoingPacketWithRespType<R>.sendAndExpect(): R = sendAndExpect(handler)
protected suspend fun <R : Packet?> OutgoingPacketWithRespType<R>.sendAndExpect(): R =
handler.sendAndExpect(this)
abstract suspend fun doLogin()
}
@ -300,7 +302,7 @@ internal class SsoProcessorImpl(
private inner class FastLoginImpl(handler: NetworkHandler) : LoginStrategy(handler) {
override suspend fun doLogin() {
val login10 = WtLogin10(client).sendAndExpect(handler)
val login10 = handler.sendAndExpect(WtLogin10(client))
check(login10 is LoginPacketResponse.Success) { "Fast login failed: $login10" }
}
}

View File

@ -127,6 +127,12 @@ internal interface NetworkHandler : CoroutineScope {
suspend fun resumeConnection()
suspend fun <P : Packet?> sendAndExpect(
packet: OutgoingPacketWithRespType<P>,
timeout: Long = 5000,
attempts: Int = 2
): P
/**
* Sends [packet], suspends and expects to receive a response from the server.
*
@ -139,7 +145,8 @@ internal interface NetworkHandler : CoroutineScope {
*
* @param attempts ranges `1..INFINITY`
*/
suspend fun sendAndExpect(packet: OutgoingPacket, timeout: Long = 5000, attempts: Int = 2): Packet?
suspend fun <P : Packet?> sendAndExpect(packet: OutgoingPacket, timeout: Long = 5000, attempts: Int = 2): P
/**
* Sends [packet] and does not expect any response.
@ -163,32 +170,6 @@ internal interface NetworkHandler : CoroutineScope {
///////////////////////////////////////////////////////////////////////////
// compatibility
///////////////////////////////////////////////////////////////////////////
/**
* @suppress This is for compatibility with old code. Use [sendWithoutExpect] without extension receiver instead.
*/
suspend fun OutgoingPacket.sendWithoutExpect(
antiCollisionParam: Any? = null,
) = this@NetworkHandler.sendWithoutExpect(this)
/**
* @suppress This is for compatibility with old code. Use [sendAndExpect] without extension receiver instead.
*/
@Suppress("UNCHECKED_CAST")
suspend fun <R> OutgoingPacket.sendAndExpect(
timeoutMillis: Long = 5000,
retry: Int = 2,
antiCollisionParam: Any? = null, // signature collision
): R = sendAndExpect(this, timeoutMillis, retry) as R
/**
* @suppress This is for compatibility with old code. Use [sendAndExpect] without extension receiver instead.
*/
@Suppress("UNCHECKED_CAST")
suspend fun <R : Packet?> OutgoingPacketWithRespType<R>.sendAndExpect(
timeoutMillis: Long = 5000,
retry: Int = 2,
): R = sendAndExpect(this, timeoutMillis, retry) as R
}
internal val NetworkHandler.logger: MiraiLogger get() = context.logger

View File

@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.network.handler.selector.NetworkHandlerSelector
import net.mamoe.mirai.internal.network.handler.state.StateObserver
import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacket
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType
import net.mamoe.mirai.internal.utils.SingleEntrantLock
import net.mamoe.mirai.internal.utils.fromMiraiLogger
import net.mamoe.mirai.internal.utils.subLogger
@ -93,7 +94,7 @@ internal abstract class NetworkHandlerSupport(
}
}
final override suspend fun sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int): Packet? {
final override suspend fun <P : Packet?> sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int): P {
require(attempts >= 1) { "attempts must be at least 1." }
val listener = PacketListener(packet.commandName, packet.sequenceId)
packetListeners.add(listener)
@ -103,9 +104,10 @@ internal abstract class NetworkHandlerSupport(
context[PacketLoggingStrategy].logSent(logger, packet)
sendPacketImpl(packet)
try {
@Suppress("UNCHECKED_CAST")
return withTimeout(timeout) {
listener.result.await()
}
} as P
} catch (e: TimeoutCancellationException) {
collectException(e)
}
@ -122,6 +124,12 @@ internal abstract class NetworkHandlerSupport(
}
}
final override suspend fun <P : Packet?> sendAndExpect(
packet: OutgoingPacketWithRespType<P>,
timeout: Long,
attempts: Int
): P = sendAndExpect(packet as OutgoingPacket, timeout, attempts)
final override suspend fun sendWithoutExpect(packet: OutgoingPacket) {
context[PacketLoggingStrategy].logSent(logger, packet)
sendPacketImpl(packet)

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.handler.selector
@ -13,10 +13,12 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.isActive
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType
import net.mamoe.mirai.utils.addNameHierarchically
import net.mamoe.mirai.utils.childScope
import kotlin.coroutines.CoroutineContext
@ -70,9 +72,15 @@ internal open class SelectorNetworkHandler<out H : NetworkHandler>(
instance() // the selector will resume connection for us.
}
override suspend fun sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int) =
override suspend fun <P : Packet?> sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int): P =
instance().sendAndExpect(packet, timeout, attempts)
override suspend fun <P : Packet?> sendAndExpect(
packet: OutgoingPacketWithRespType<P>,
timeout: Long,
attempts: Int
): P = instance().sendAndExpect(packet, timeout, attempts)
override suspend fun sendWithoutExpect(packet: OutgoingPacket) = instance().sendWithoutExpect(packet)
override fun close(cause: Throwable?) {
if (cause is NetworkException && cause.recoverable) {

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.notice
@ -25,7 +25,6 @@ import net.mamoe.mirai.internal.getGroupByUin
import net.mamoe.mirai.internal.network.protocol.data.jce.StTroopNum
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
internal interface NewContactSupport { // can be a marker interface when context receivers are available.
@ -89,9 +88,10 @@ internal interface NewContactSupport { // can be a marker interface when context
}
private suspend fun QQAndroidBot.getNewGroup(groupCode: Long): GroupImpl? {
val troopNum = FriendList.GetTroopListSimplify(client)
.sendAndExpect(network, timeoutMillis = 10_000, retry = 5)
.groups.firstOrNull { it.groupCode == groupCode } ?: return null
val troopNum = network.sendAndExpect(
FriendList.GetTroopListSimplify(client),
timeout = 10_000, attempts = 5
).groups.firstOrNull { it.groupCode == groupCode } ?: return null
return getNewGroup(troopNum)
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.notice
@ -106,14 +106,10 @@ internal class UnconsumedNoticesAlerter(
// 前 4 byte 是群号
}
84, 87 -> { // 请求入群验证 和 被邀请入群
bot.network.run {
NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect()
}
bot.network.sendWithoutExpect(NewContact.SystemMsgNewGroup(bot.client))
}
187 -> { // 请求加好友验证
bot.network.run {
NewContact.SystemMsgNewFriend(bot.client).sendWithoutExpect()
}
bot.network.sendWithoutExpect(NewContact.SystemMsgNewFriend(bot.client))
}
else -> {
logger.debug { "unknown PbGetMsg type ${data.msgHead.msgType}, data=${data.msgBody.msgContent.toUHexString()}" }

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.notice.priv
@ -35,7 +35,6 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x44.Subms
import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0xb3.SubMsgType0xb3
import net.mamoe.mirai.internal.network.protocol.packet.chat.NewContact
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList.GetFriendGroupList
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.structureToString
@ -92,9 +91,7 @@ internal class FriendNoticeProcessor(
val nick = fromNick.ifEmpty { authNick }.ifEmpty { pbNick }
collect(StrangerAddEvent(bot.addNewStranger(StrangerInfoImpl(id, nick, fromGroup)) ?: return))
//同时需要请求好友验证消息(有新请求需要同意)
bot.network.run {
NewContact.SystemMsgNewFriend(bot.client).sendWithoutExpect()
}
bot.network.sendWithoutExpect(NewContact.SystemMsgNewFriend(bot.client))
}
}
@ -252,7 +249,8 @@ internal class FriendNoticeProcessor(
3, 9, 10 -> {
if (bot.getFriend(fuin) != null) return
val response = GetFriendGroupList.forSingleFriend(bot.client, fuin).sendAndExpect(bot)
val response = bot.network.sendAndExpect(GetFriendGroupList.forSingleFriend(bot.client, fuin))
val info = response.friendList.firstOrNull() ?: return
collect(
FriendAddEvent(bot.addNewFriendAndRemoveStranger(info.toMiraiFriendInfo()) ?: return),
@ -274,7 +272,7 @@ internal class FriendNoticeProcessor(
val added = bot.addNewFriendAndRemoveStranger(info) ?: return
collect(FriendAddEvent(added))
if (removed != null) collect(StrangerRelationChangeEvent.Friended(removed, added))
}
}
private fun NoticePipelineContext.handlePrivateNudge(body: Submsgtype0x122.Submsgtype0x122.MsgBody) {
val action = body.msgTemplParam["action_str"].orEmpty()

View File

@ -11,12 +11,10 @@ package net.mamoe.mirai.internal.network.protocol.packet
import kotlinx.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.appClientVersion
import net.mamoe.mirai.internal.network.components.EcdhInitialPublicKeyUpdater
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.utils.io.encryptAndWrite
import net.mamoe.mirai.internal.utils.io.writeHex
import net.mamoe.mirai.internal.utils.io.writeIntLVPacket
@ -76,36 +74,6 @@ internal class IncomingPacket private constructor(
}
}
@Suppress("UNCHECKED_CAST")
internal suspend inline fun <E : Packet> OutgoingPacketWithRespType<E>.sendAndExpect(
network: NetworkHandler,
timeoutMillis: Long = 5000,
retry: Int = 2
): E = network.sendAndExpect(this, timeoutMillis, retry) as E
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "UNCHECKED_CAST")
@kotlin.internal.LowPriorityInOverloadResolution
internal suspend inline fun <E : Packet> OutgoingPacket.sendAndExpect(
network: NetworkHandler,
timeoutMillis: Long = 5000,
retry: Int = 2
): E = network.sendAndExpect(this, timeoutMillis, retry) as E
internal suspend inline fun <E : Packet> OutgoingPacketWithRespType<E>.sendAndExpect(
bot: QQAndroidBot,
timeoutMillis: Long = 5000,
retry: Int = 2
): E = (this@sendAndExpect as OutgoingPacket).sendAndExpect(bot.network, timeoutMillis, retry)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "UNCHECKED_CAST")
@kotlin.internal.LowPriorityInOverloadResolution
internal suspend inline fun <E : Packet> OutgoingPacket.sendAndExpect(
bot: QQAndroidBot,
timeoutMillis: Long = 5000,
retry: Int = 2
): E = bot.network.sendAndExpect(this, timeoutMillis, retry) as E
@Suppress("DuplicatedCode")
internal inline fun <R : Packet?> OutgoingPacketFactory<R>.buildOutgoingUniPacket(
client: QQAndroidClient,

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.chat
@ -16,7 +16,6 @@ import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.data.proto.Cmd0xed3
import net.mamoe.mirai.internal.network.protocol.data.proto.OidbSso
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
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.loadAs
@ -38,7 +37,7 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
client: QQAndroidClient,
nudgeTargetId: Long,
messageReceiverUin: Long,
): OutgoingPacket = buildOutgoingUniPacket(client) {
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(),
OidbSso.OIDBSSOPkg(
@ -57,7 +56,7 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
client: QQAndroidClient,
messageReceiverGroupCode: Long,
nudgeTargetId: Long,
): OutgoingPacket = buildOutgoingUniPacket(client) {
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(),
OidbSso.OIDBSSOPkg(

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.chat
@ -24,6 +24,7 @@ import net.mamoe.mirai.internal.network.protocol.data.jce.stUinInfo
import net.mamoe.mirai.internal.network.protocol.data.proto.*
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType
import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.internal.network.subAppId
import net.mamoe.mirai.internal.utils.io.serialization.*
@ -41,7 +42,7 @@ internal class TroopManagement {
groupCode: Long,
memberUin: Long,
timeInSecond: Int
): OutgoingPacket {
): OutgoingPacketWithRespType<Response> {
require(timeInSecond in 0..30.daysToSeconds)
return buildOutgoingUniPacket(client) {
writeProtoBuf(
@ -73,7 +74,7 @@ internal class TroopManagement {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long
): OutgoingPacket {
): OutgoingPacketWithRespType<GroupInfoImpl> {
return buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(),
@ -382,7 +383,7 @@ internal class TroopManagement {
client: QQAndroidClient,
member: Member,
newName: String
): OutgoingPacket {
): OutgoingPacketWithRespType<Response> {
return buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.chat.image
@ -14,7 +14,6 @@ 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.Cmd0x352
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
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
@ -24,8 +23,8 @@ internal class LongConn {
internal object OffPicUp : OutgoingPacketFactory<OffPicUp.Response>("LongConn.OffPicUp") {
operator fun invoke(client: QQAndroidClient, req: Cmd0x352.TryUpImgReq): OutgoingPacket {
return buildOutgoingUniPacket(client) {
operator fun invoke(client: QQAndroidClient, req: Cmd0x352.TryUpImgReq) =
buildOutgoingUniPacket(client) {
writeProtoBuf(
Cmd0x352.ReqBody.serializer(),
Cmd0x352.ReqBody(
@ -37,7 +36,6 @@ internal class LongConn {
)
)
}
}
//08 01 12 7D 08 00 10 AB E1 9D DF 07 18 00 28 01 32 1C 0A 10 8E C4 9D 72 26 AE 20 C0 5D A2 B6 78 4D 12 B7 3A 10 E9 07 18 86 1F 20 30 28 30 52 25 2F 61 30 30 39 32 64 61 39 2D 64 39 31 38 2D 34 38 31 62 2D 38 34 30 63 2D 33 32 33 64 64 33 39 33 34 35 37 63 5A 25 2F 61 30 30 39 32 64 61 39 2D 64 39 31 38 2D 34 38 31 62 2D 38 34 30 63 2D 33 32 33 64 64 33 39 33 34 35 37 63 60 00 68 80 40 20 01

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
@ -31,21 +31,21 @@ internal object MessageSvcPbDeleteMsg : OutgoingPacketFactory<Nothing?>("Message
)
}
internal suspend fun delete(bot: QQAndroidBot, messages: List<MsgComm.Msg>) =
bot.network.run {
val map = messages.map {
MsgSvc.PbDeleteMsgReq.MsgItem(
fromUin = it.msgHead.fromUin,
toUin = it.msgHead.toUin,
// 群为84、好友为187。群通过其他方法删除但测试结果显示通过187也能删除群消息。
msgType = 187,
msgSeq = it.msgHead.msgSeq,
msgUid = it.msgHead.msgUid,
)
}
MessageSvcPbDeleteMsg(bot.client, map).sendWithoutExpect()
internal suspend fun delete(bot: QQAndroidBot, messages: List<MsgComm.Msg>) {
val map = messages.map {
MsgSvc.PbDeleteMsgReq.MsgItem(
fromUin = it.msgHead.fromUin,
toUin = it.msgHead.toUin,
// 群为84、好友为187。群通过其他方法删除但测试结果显示通过187也能删除群消息。
msgType = 187,
msgSeq = it.msgHead.msgSeq,
msgUid = it.msgHead.msgUid,
)
}
bot.network.sendWithoutExpect(MessageSvcPbDeleteMsg(bot.client, map))
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot) = null
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@ -113,9 +113,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
// .warning { "MessageSvcPushNotify: result != 0, result = ${resp.result}, errorMsg=${resp.errmsg}" }
bot.network.launch(CoroutineName("MessageSvcPushNotify.retry")) {
delay(500 + Random.nextLong(0, 1000))
bot.network.run {
MessageSvcPbGetMsg(bot.client, syncCookie = null).sendWithoutExpect()
}
bot.network.sendWithoutExpect(MessageSvcPbGetMsg(bot.client, syncCookie = null))
}
return EmptyResponse(bot)
}
@ -170,24 +168,24 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
}
MsgSvc.SyncFlag.START -> {
network.run {
network.sendAndExpect(
MessageSvcPbGetMsg(
client,
MsgSvc.SyncFlag.CONTINUE,
bot.syncController.syncCookie,
).sendAndExpect()
}
), 5000, 2
)
return
}
MsgSvc.SyncFlag.CONTINUE -> {
network.run {
network.sendAndExpect(
MessageSvcPbGetMsg(
client,
MsgSvc.SyncFlag.CONTINUE,
bot.syncController.syncCookie,
).sendAndExpect()
}
), 5000, 2
)
return
}
}

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* 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.
* 此源代码的使用受 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
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.chat.receive
@ -17,13 +17,12 @@ import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.buildResponseUniPacket
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin10
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
internal object OnlinePushSidExpired : IncomingPacketFactory<Packet?>("OnlinePush.SidTicketExpired") {
override suspend fun QQAndroidBot.handle(packet: Packet?, sequenceId: Int): OutgoingPacket {
WtLogin10(client, mainSigMap = 3554528).sendAndExpect(bot)
StatSvc.Register.online(client).sendAndExpect(bot)
bot.network.sendAndExpect(WtLogin10(client, mainSigMap = 3554528))
bot.network.sendAndExpect(StatSvc.Register.online(client))
return buildResponseUniPacket(client, sequenceId = sequenceId)
}

View File

@ -14,7 +14,6 @@ import net.mamoe.mirai.internal.message.FriendImage
import net.mamoe.mirai.internal.message.OfflineGroupImage
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.utils.ResourceAccessLock
import net.mamoe.mirai.utils.UnsafeMutableNonNullProperty
import net.mamoe.mirai.utils.currentTimeMillis
@ -117,13 +116,15 @@ internal open class ImagePatcher {
val bot = group.bot
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = group.id,
md5 = image.md5,
size = 1,
).sendAndExpect(bot)
val response: ImgStore.GroupPicUp.Response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = group.id,
md5 = image.md5,
size = 1,
)
)
when (response) {
is ImgStore.GroupPicUp.Response.Failed -> {
@ -154,13 +155,15 @@ internal open class ImagePatcher {
val bot = group.bot
val response = ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = group.id,
md5 = image.md5,
size = image.size
).sendAndExpect(bot.network)
val response = bot.network.sendAndExpect(
ImgStore.GroupPicUp(
bot.client,
uin = bot.id,
groupCode = group.id,
md5 = image.md5,
size = image.size
)
)
return OfflineGroupImage(
imageId = image.imageId,

View File

@ -26,7 +26,6 @@ import net.mamoe.mirai.internal.network.protocol
import net.mamoe.mirai.internal.network.protocol.data.proto.*
import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.toResult
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.FileMessage
@ -222,12 +221,14 @@ internal class RemoteFileImpl(
return flow {
var index = 0
while (true) {
val list = FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = info.id,
startIndex = index
).sendAndExpect(bot).toResult("RemoteFile.listFiles").getOrThrow()
val list = bot.network.sendAndExpect(
FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = info.id,
startIndex = index
)
).toResult("RemoteFile.listFiles").getOrThrow()
index += list.itemList.size
if (list.int32RetCode != 0) return@flow
@ -275,12 +276,14 @@ internal class RemoteFileImpl(
private var ended = false
private suspend fun updateItems() {
val list = FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = path,
startIndex = index
).sendAndExpect(bot).toResult("RemoteFile.listFiles").getOrThrow()
val list = bot.network.sendAndExpect(
FileManagement.GetFileList(
client,
groupCode = contact.id,
folderId = path,
startIndex = index
)
).toResult("RemoteFile.listFiles").getOrThrow()
if (list.int32RetCode != 0 || list.itemList.isEmpty()) {
ended = true
return
@ -356,13 +359,15 @@ internal class RemoteFileImpl(
if (!info.isOperable()) return false
return when {
info.isFile -> {
FileManagement.DeleteFile(
client,
groupCode = contact.id,
busId = info.busId,
fileId = info.id,
parentFolderId = info.parentFolderId,
).sendAndExpect(bot).toResult("RemoteFile.delete", checkResp = false).getOrThrow().int32RetCode == 0
bot.network.sendAndExpect(
FileManagement.DeleteFile(
client,
groupCode = contact.id,
busId = info.busId,
fileId = info.id,
parentFolderId = info.parentFolderId,
)
).toResult("RemoteFile.delete", checkResp = false).getOrThrow().int32RetCode == 0
}
// recursively -> {
// this.listFiles().collect { child ->
@ -372,9 +377,11 @@ internal class RemoteFileImpl(
// }
else -> {
// natively 'recursive'
FileManagement.DeleteFolder(
client, contact.id, info.id
).sendAndExpect(bot).toResult("RemoteFile.delete").getOrThrow().int32RetCode == 0
bot.network.sendAndExpect(
FileManagement.DeleteFolder(
client, contact.id, info.id
)
).toResult("RemoteFile.delete").getOrThrow().int32RetCode == 0
}
}
}
@ -387,11 +394,13 @@ internal class RemoteFileImpl(
val info = getFileFolderInfo() ?: return false
if (!info.isOperable()) return false
return if (info.isFile) {
FileManagement.RenameFile(client, contact.id, info.busId, info.id, info.parentFolderId, normalized)
} else {
FileManagement.RenameFolder(client, contact.id, info.id, normalized)
}.sendAndExpect(bot).toResult("RemoteFile.renameTo", checkResp = false).getOrThrow().int32RetCode == 0
return bot.network.sendAndExpect(
if (info.isFile) {
FileManagement.RenameFile(client, contact.id, info.busId, info.id, info.parentFolderId, normalized)
} else {
FileManagement.RenameFolder(client, contact.id, info.id, normalized)
}
).toResult("RemoteFile.renameTo", checkResp = false).getOrThrow().int32RetCode == 0
}
/**
@ -424,10 +433,18 @@ internal class RemoteFileImpl(
if (!info.isOperable()) return false
return if (info.isFile) {
val newParentId = target.parent?.checkIsImpl()?.getIdSmart() ?: return false
FileManagement.MoveFile(client, contact.id, info.busId, info.id, info.parentFolderId, newParentId)
.sendAndExpect(bot).toResult("RemoteFile.moveTo", checkResp = false).getOrThrow().int32RetCode == 0
bot.network.sendAndExpect(
FileManagement.MoveFile(
client,
contact.id,
info.busId,
info.id,
info.parentFolderId,
newParentId
)
).toResult("RemoteFile.moveTo", checkResp = false).getOrThrow().int32RetCode == 0
} else {
return FileManagement.RenameFolder(client, contact.id, info.id, target.name).sendAndExpect(bot)
return bot.network.sendAndExpect(FileManagement.RenameFolder(client, contact.id, info.id, target.name))
.toResult("RemoteFile.moveTo", checkResp = false).getOrThrow().int32RetCode == 0
}
}
@ -439,8 +456,8 @@ internal class RemoteFileImpl(
val parentFolderId: String = parent?.getIdSmart() ?: return false
return FileManagement.CreateFolder(client, contact.id, parentFolderId, this.name)
.sendAndExpect(bot).toResult("RemoteFile.mkdir", checkResp = false).getOrThrow().int32RetCode == 0
return bot.network.sendAndExpect(FileManagement.CreateFolder(client, contact.id, parentFolderId, this.name))
.toResult("RemoteFile.mkdir", checkResp = false).getOrThrow().int32RetCode == 0
}
private suspend fun upload0(
@ -449,13 +466,15 @@ internal class RemoteFileImpl(
): Oidb0x6d6.UploadFileRspBody? = resource.withAutoClose {
val parent = parent ?: return null
val parentInfo = parent.getFileFolderInfo() ?: return null
val resp = FileManagement.RequestUpload(
client,
groupCode = contact.id,
folderId = parentInfo.id,
resource = resource,
filename = this.name
).sendAndExpect(bot).toResult("RemoteFile.upload").getOrThrow()
val resp = bot.network.sendAndExpect(
FileManagement.RequestUpload(
client,
groupCode = contact.id,
folderId = parentInfo.id,
resource = resource,
filename = this.name
)
).toResult("RemoteFile.upload").getOrThrow()
if (resp.boolFileExist) {
return resp
}
@ -585,12 +604,14 @@ internal class RemoteFileImpl(
override suspend fun getDownloadInfo(): RemoteFile.DownloadInfo? {
val info = getFileFolderInfo() ?: return null
if (!info.isFile) return null
val resp = FileManagement.RequestDownload(
client,
groupCode = contact.id,
busId = info.busId,
fileId = info.id
).sendAndExpect(bot).toResult("RemoteFile.getDownloadInfo").getOrThrow()
val resp = bot.network.sendAndExpect(
FileManagement.RequestDownload(
client,
groupCode = contact.id,
busId = info.busId,
fileId = info.id
)
).toResult("RemoteFile.getDownloadInfo").getOrThrow()
return RemoteFile.DownloadInfo(
filename = name,