Generalize ImagePatcher

This commit is contained in:
Him188 2022-05-23 13:26:26 +01:00
parent 52968b172f
commit c510a49adc
5 changed files with 82 additions and 24 deletions

View File

@ -47,6 +47,7 @@ import net.mamoe.mirai.internal.network.notice.priv.OtherClientNoticeProcessor
import net.mamoe.mirai.internal.network.notice.priv.PrivateMessageProcessor
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.utils.ImagePatcher
import net.mamoe.mirai.internal.utils.ImagePatcherImpl
import net.mamoe.mirai.internal.utils.subLogger
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiLogger
@ -249,7 +250,7 @@ internal open class QQAndroidBot constructor(
AccountSecretsManager,
configuration.createAccountsSecretsManager(bot.logger.subLogger("AccountSecretsManager")),
)
set(ImagePatcher, ImagePatcher())
set(ImagePatcher, ImagePatcherImpl())
}
/**

View File

@ -19,7 +19,7 @@ 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.utils.ImagePatcher
import net.mamoe.mirai.internal.utils.ImagePatcher.Companion.withCache
import net.mamoe.mirai.internal.utils.withCache
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.ImageType
import net.mamoe.mirai.message.data.InternalImageProtocol

View File

@ -10,7 +10,6 @@
package net.mamoe.mirai.internal.message.protocol.impl
import net.mamoe.mirai.contact.User
import net.mamoe.mirai.internal.asQQAndroidBot
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.message.data.transform
import net.mamoe.mirai.internal.message.image.*
@ -46,7 +45,7 @@ internal class ImageProtocol : MessageProtocol() {
val contact = attributes[CONTACT]
if (contact !is GroupImpl) return
val patcher = contact.bot.asQQAndroidBot().components[ImagePatcher]
val patcher = contact.bot.components[ImagePatcher]
currentMessageChain = currentMessageChain.transform { element ->
when (element) {
is OfflineGroupImage -> {

View File

@ -19,34 +19,51 @@ import net.mamoe.mirai.utils.UnsafeMutableNonNullProperty
import net.mamoe.mirai.utils.currentTimeMillis
import net.mamoe.mirai.utils.unsafeMutableNonNullPropertyOf
internal open class ImagePatcher {
companion object : ComponentKey<ImagePatcher> {
inline fun <T> ImageCache.withCache(action: (ImageCache) -> T): T {
return try {
action(this)
} finally {
this.accessLock.release()
}
}
}
internal interface ImagePatcher {
fun findCacheByImageId(id: String): ImageCache?
data class ImageCache(
var updateTime: Long = 0,
val id: UnsafeMutableNonNullProperty<String> = unsafeMutableNonNullPropertyOf(),
// OGI: OfflineGroupImage
val cacheOGI: UnsafeMutableNonNullProperty<OfflineGroupImage> = unsafeMutableNonNullPropertyOf(),
val accessLock: ResourceAccessLock = ResourceAccessLock(),
fun putCache(image: OfflineGroupImage)
suspend fun patchOfflineGroupImage(
group: GroupImpl,
image: OfflineGroupImage,
)
suspend fun patchFriendImageToGroupImage(
group: GroupImpl,
image: FriendImage,
): OfflineGroupImage
companion object : ComponentKey<ImagePatcher>
}
internal data class ImageCache(
var updateTime: Long = 0,
val id: UnsafeMutableNonNullProperty<String> = unsafeMutableNonNullPropertyOf(),
// OGI: OfflineGroupImage
val cacheOGI: UnsafeMutableNonNullProperty<OfflineGroupImage> = unsafeMutableNonNullPropertyOf(),
val accessLock: ResourceAccessLock = ResourceAccessLock(),
)
internal inline fun <T> ImageCache.withCache(action: (ImageCache) -> T): T {
return try {
action(this)
} finally {
this.accessLock.release()
}
}
internal open class ImagePatcherImpl : ImagePatcher {
val caches: Array<ImageCache> = Array(20) { ImageCache() }
fun findCache(id: String): ImageCache? {
return caches.firstOrNull { it.id.value0 == id && it.accessLock.tryUse() }
}
fun findCacheByImageId(id: String): ImageCache? = findCache(calcInternalIdByImageId(id))
override fun findCacheByImageId(id: String): ImageCache? = findCache(calcInternalIdByImageId(id))
fun putCache(image: OfflineGroupImage) {
override fun putCache(image: OfflineGroupImage) {
putCache(calcInternalIdByImageId(image.imageId)).cacheOGI.value0 = image
}
@ -101,7 +118,7 @@ internal open class ImagePatcher {
return imageId.substring(1, imageId.indexOf('}'))
}
suspend fun patchOfflineGroupImage(
override suspend fun patchOfflineGroupImage(
group: GroupImpl,
image: OfflineGroupImage,
) {
@ -144,7 +161,7 @@ internal open class ImagePatcher {
/**
* Ensures server holds the cache
*/
suspend fun patchFriendImageToGroupImage(
override suspend fun patchFriendImageToGroupImage(
group: GroupImpl,
image: FriendImage,
): OfflineGroupImage {

View File

@ -0,0 +1,41 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.framework.components
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.message.image.FriendImage
import net.mamoe.mirai.internal.message.image.OfflineGroupImage
import net.mamoe.mirai.internal.utils.ImageCache
import net.mamoe.mirai.internal.utils.ImagePatcher
import net.mamoe.mirai.internal.utils.ImagePatcherImpl
internal class TestImagePatcher : ImagePatcher {
val patchedOfflineGroupImages: MutableList<OfflineGroupImage> = mutableListOf()
val patchedFriendImages: MutableList<FriendImage> = mutableListOf()
private val patcher = ImagePatcherImpl()
override fun findCacheByImageId(id: String): ImageCache? {
return patcher.findCacheByImageId(id)
}
override fun putCache(image: OfflineGroupImage) {
patcher.putCache(image)
}
override suspend fun patchOfflineGroupImage(group: GroupImpl, image: OfflineGroupImage) {
patchedOfflineGroupImages.add(image)
}
override suspend fun patchFriendImageToGroupImage(group: GroupImpl, image: FriendImage): OfflineGroupImage {
patchedFriendImages.add(image)
return OfflineGroupImage(image.imageId, image.width, image.height, image.size, image.imageType, image.isEmoji)
}
}