diff --git a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt index 29a8837fb..4bcc92ef7 100644 --- a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt +++ b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt @@ -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() + } + + 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() + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/contact/FriendImpl.kt b/mirai-core/src/commonMain/kotlin/contact/FriendImpl.kt index c15a1d1a7..a138a3648 100644 --- a/mirai-core/src/commonMain/kotlin/contact/FriendImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/FriendImpl.kt @@ -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() - } - - @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() - } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index 14468a5b0..b33ec213f 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -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 diff --git a/mirai-core/src/commonMain/kotlin/contact/MemberImpl.kt b/mirai-core/src/commonMain/kotlin/contact/MemberImpl.kt index 366e489dc..9faacaccf 100644 --- a/mirai-core/src/commonMain/kotlin/contact/MemberImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/MemberImpl.kt @@ -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) {