Move FriendImpl.uploadImage implementation to AbstractUser.uploadImage, simplify MemberImpl

This commit is contained in:
Him188 2020-12-23 19:55:27 +08:00
parent e978918303
commit 960b67f829
4 changed files with 86 additions and 105 deletions

View File

@ -11,7 +11,22 @@ package net.mamoe.mirai.internal.contact
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.User
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BeforeImageUploadEvent
import net.mamoe.mirai.event.events.EventCancelledException
import net.mamoe.mirai.event.events.ImageUploadEvent
import net.mamoe.mirai.internal.network.highway.postImage
import net.mamoe.mirai.internal.network.highway.sizeToString
import net.mamoe.mirai.internal.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.internal.utils.MiraiPlatformUtils
import net.mamoe.mirai.internal.utils.toUHexString
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.verbose
import kotlin.coroutines.CoroutineContext
import kotlin.math.roundToInt
import kotlin.time.measureTime
internal abstract class AbstractUser(
bot: Bot,
@ -21,4 +36,74 @@ internal abstract class AbstractUser(
final override val id: Long = friendInfo.uin
final override val nick: String = friendInfo.nick
final override val remark: String = friendInfo.remark
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
override suspend fun uploadImage(image: ExternalImage): Image = try {
if (image.input is net.mamoe.mirai.utils.internal.DeferredReusableInput) {
image.input.init(bot.configuration.fileCacheStrategy)
}
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
}
val response = bot.network.run {
LongConn.OffPicUp(
bot.client, Cmd0x352.TryUpImgReq(
srcUin = bot.id.toInt(),
dstUin = id.toInt(),
fileId = 0,
fileMd5 = image.md5,
fileSize = image.input.size.toInt(),
fileName = image.md5.toUHexString("") + "." + image.formatName,
imgOriginal = 1
)
).sendAndExpect<LongConn.OffPicUp.Response>()
}
when (response) {
is LongConn.OffPicUp.Response.FileExists -> net.mamoe.mirai.internal.message.OfflineFriendImage(response.resourceId)
.also {
ImageUploadEvent.Succeed(this, image, it).broadcast()
}
is LongConn.OffPicUp.Response.RequireUpload -> {
bot.network.logger.verbose {
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
}
val time = measureTime {
MiraiPlatformUtils.Http.postImage(
"0x6ff0070",
bot.id,
null,
imageInput = image.input,
uKeyHex = response.uKey.toUHexString("")
)
}
bot.network.logger.verbose {
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
}
/*
HighwayHelper.uploadImageToServers(
bot,
response.serverIp.zip(response.serverPort),
response.uKey,
image,
kind = "friend",
commandId = 1
)*/
// 为什么不能 ??
net.mamoe.mirai.internal.message.OfflineFriendImage(response.resourceId).also {
ImageUploadEvent.Succeed(this, image, it).broadcast()
}
}
is LongConn.OffPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this, image, -1, response.message).broadcast()
error(response.message)
}
}
} finally {
image.input.release()
}
}

View File

@ -23,28 +23,13 @@ import kotlinx.atomicfu.atomic
import net.mamoe.mirai.LowLevelApi
import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BeforeImageUploadEvent
import net.mamoe.mirai.event.events.EventCancelledException
import net.mamoe.mirai.event.events.ImageUploadEvent
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.highway.postImage
import net.mamoe.mirai.internal.network.highway.sizeToString
import net.mamoe.mirai.internal.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.internal.utils.MiraiPlatformUtils
import net.mamoe.mirai.internal.utils.toUHexString
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.isContentNotEmpty
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.verbose
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
import kotlin.math.roundToInt
import kotlin.time.measureTime
internal class FriendInfoImpl(
@JvmField private val jceFriendInfo: net.mamoe.mirai.internal.network.protocol.data.jce.FriendInfo
@ -93,75 +78,4 @@ internal class FriendImpl(
}
override fun toString(): String = "Friend($id)"
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
override suspend fun uploadImage(image: ExternalImage): Image = try {
if (image.input is net.mamoe.mirai.utils.internal.DeferredReusableInput) {
image.input.init(bot.configuration.fileCacheStrategy)
}
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
}
val response = bot.network.run {
LongConn.OffPicUp(
bot.client, Cmd0x352.TryUpImgReq(
srcUin = bot.id.toInt(),
dstUin = id.toInt(),
fileId = 0,
fileMd5 = image.md5,
fileSize = image.input.size.toInt(),
fileName = image.md5.toUHexString("") + "." + image.formatName,
imgOriginal = 1
)
).sendAndExpect<LongConn.OffPicUp.Response>()
}
@Suppress("UNCHECKED_CAST", "DEPRECATION")
when (response) {
is LongConn.OffPicUp.Response.FileExists -> net.mamoe.mirai.internal.message.OfflineFriendImage(response.resourceId)
.also {
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
}
is LongConn.OffPicUp.Response.RequireUpload -> {
bot.network.logger.verbose {
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
}
val time = measureTime {
MiraiPlatformUtils.Http.postImage(
"0x6ff0070",
bot.id,
null,
imageInput = image.input,
uKeyHex = response.uKey.toUHexString("")
)
}
bot.network.logger.verbose {
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
}
/*
HighwayHelper.uploadImageToServers(
bot,
response.serverIp.zip(response.serverPort),
response.uKey,
image,
kind = "friend",
commandId = 1
)*/
// 为什么不能 ??
net.mamoe.mirai.internal.message.OfflineFriendImage(response.resourceId).also {
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
}
}
is LongConn.OffPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this@FriendImpl, image, -1, response.message).broadcast()
error(response.message)
}
}
} finally {
image.input.release()
}
}

View File

@ -14,7 +14,6 @@ package net.mamoe.mirai.internal.contact
import kotlinx.coroutines.launch
import net.mamoe.mirai.LowLevelApi
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
@ -232,7 +231,6 @@ internal class GroupImpl(
)
}
return MemberImpl(
Mirai._lowLevelNewFriend(bot, memberInfo) as FriendImpl,
this,
this.coroutineContext,
memberInfo

View File

@ -19,7 +19,6 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.message.MessageSourceToTempImpl
import net.mamoe.mirai.internal.message.ensureSequenceIdAvailable
import net.mamoe.mirai.internal.message.firstIsInstanceOrNull
@ -29,7 +28,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcP
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToTemp
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef
@ -40,24 +38,15 @@ import kotlin.coroutines.CoroutineContext
@OptIn(LowLevelApi::class)
@Suppress("MemberVisibilityCanBePrivate")
internal class MemberImpl constructor(
val qq: FriendImpl, // 不要 WeakRef
group: GroupImpl,
coroutineContext: CoroutineContext,
memberInfo: MemberInfo
) : NormalMember {
) : NormalMember, AbstractUser(group.bot, coroutineContext, memberInfo) {
override val group: GroupImpl by group.unsafeWeakRef()
override val coroutineContext: CoroutineContext = coroutineContext + SupervisorJob(coroutineContext[Job])
@Suppress("unused") // false positive
val lastMessageSequence: AtomicInt = atomic(-1)
override val id: Long = qq.id
override val nick: String = qq.nick
override val remark: String
get() {
return (this.asFriendOrNull() ?: return "").remark
}
override fun toString(): String = "Member($id)"
@Suppress("UNCHECKED_CAST")
@ -115,9 +104,6 @@ internal class MemberImpl constructor(
return result.getOrThrow()
}
@JvmSynthetic
override suspend fun uploadImage(image: ExternalImage): Image = qq.uploadImage(image)
override var permission: MemberPermission = memberInfo.permission
@Suppress("PropertyName")
@ -181,8 +167,6 @@ internal class MemberImpl constructor(
}
}
override val bot: QQAndroidBot get() = qq.bot
@JvmSynthetic
override suspend fun mute(durationSeconds: Int) {
check(this.id != bot.id) {