commit f2813d45c7cebbe59e0f37cd40fc303f536e209b
parent 3fbe5ef121190e2bd39b849c46cdf6ca91db8dc8
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Sun,  8 Oct 2023 00:35:57 +0200

fix(core/downloader): better duplicate handling
- fix runOnUIThread

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt | 12++++++++++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/util/export/MessageExporter.kt | 4++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt | 9+++++----
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/decoder/MessageDecoder.kt | 17+++++++++++------
4 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt @@ -67,6 +67,10 @@ class ModContext { } fun runOnUiThread(runnable: () -> Unit) { + if (Looper.myLooper() == Looper.getMainLooper()) { + runnable() + return + } Handler(Looper.getMainLooper()).post { runCatching(runnable).onFailure { Logger.xposedLog("UI thread runnable failed", it) @@ -86,11 +90,15 @@ class ModContext { } fun shortToast(message: Any?) { - Toast.makeText(androidContext, message.toString(), Toast.LENGTH_SHORT).show() + runOnUiThread { + Toast.makeText(androidContext, message.toString(), Toast.LENGTH_SHORT).show() + } } fun longToast(message: Any?) { - Toast.makeText(androidContext, message.toString(), Toast.LENGTH_LONG).show() + runOnUiThread { + Toast.makeText(androidContext, message.toString(), Toast.LENGTH_LONG).show() + } } fun softRestartApp(saveSettings: Boolean = false) { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/util/export/MessageExporter.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/util/export/MessageExporter.kt @@ -119,7 +119,7 @@ class MessageExporter( }.forEach { message -> threadPool.execute { MessageDecoder.decode(message.messageContent).forEach decode@{ attachment -> - val protoMediaReference = Base64.UrlSafe.decode(attachment.mediaKey ?: return@decode) + val protoMediaReference = Base64.UrlSafe.decode(attachment.mediaUrlKey ?: return@decode) runCatching { RemoteMediaResolver.downloadBoltMedia(protoMediaReference, decryptionCallback = { @@ -291,7 +291,7 @@ class MessageExporter( if (attachments.type == AttachmentType.STICKER) //TODO: implement stickers return@attachments add(JsonObject().apply { - addProperty("key", attachments.mediaKey?.replace("=", "")) + addProperty("key", attachments.mediaUrlKey?.replace("=", "")) addProperty("type", attachments.type.toString()) add("encryption", attachments.attachmentInfo?.encryption?.let { encryption -> JsonObject().apply { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt @@ -289,9 +289,10 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp val author = context.database.getFriendInfo(senderId) ?: return val authorUsername = author.usernameForSorting!! + val mediaId = paramMap["MEDIA_ID"]?.toString()?.split("-")?.getOrNull(1) ?: "" downloadOperaMedia(provideDownloadManagerClient( - mediaIdentifier = "$conversationId$senderId${conversationMessage.serverMessageId}", + mediaIdentifier = "$conversationId$senderId${conversationMessage.serverMessageId}$mediaId", mediaAuthor = authorUsername, downloadSource = MediaDownloadSource.CHAT_MEDIA, friendInfo = author @@ -533,12 +534,12 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp attachments.forEach { attachment -> runCatching { provideDownloadManagerClient( - mediaIdentifier = "${message.clientConversationId}${message.senderId}${message.serverMessageId}${attachment.attachmentInfo?.encryption?.iv}", + mediaIdentifier = "${message.clientConversationId}${message.senderId}${message.serverMessageId}${attachment.mediaUniqueId}", downloadSource = MediaDownloadSource.CHAT_MEDIA, mediaAuthor = authorName, friendInfo = friendInfo ).downloadSingleMedia( - mediaData = attachment.mediaKey!!, + mediaData = attachment.mediaUrlKey!!, mediaType = DownloadMediaType.PROTO_MEDIA, encryption = attachment.attachmentInfo?.encryption, attachmentType = attachment.type @@ -614,7 +615,7 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp val firstAttachment = decodedAttachments.first() val previewCoroutine = async { - val downloadedMedia = RemoteMediaResolver.downloadBoltMedia(Base64.decode(firstAttachment.mediaKey!!), decryptionCallback = { + val downloadedMedia = RemoteMediaResolver.downloadBoltMedia(Base64.decode(firstAttachment.mediaUrlKey!!), decryptionCallback = { firstAttachment.attachmentInfo?.encryption?.decryptInputStream(it) ?: it }) ?: return@async null diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/decoder/MessageDecoder.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/decoder/MessageDecoder.kt @@ -10,17 +10,22 @@ import kotlin.io.encoding.Base64 import kotlin.io.encoding.ExperimentalEncodingApi data class DecodedAttachment( - val mediaKey: String?, + val mediaUrlKey: String?, val type: AttachmentType, val attachmentInfo: AttachmentInfo? -) +) { + @OptIn(ExperimentalEncodingApi::class) + val mediaUniqueId: String? by lazy { + runCatching { Base64.UrlSafe.decode(mediaUrlKey.toString()) }.getOrNull()?.let { ProtoReader(it).getString(2, 2) } + } +} @OptIn(ExperimentalEncodingApi::class) object MessageDecoder { private val gson = GsonBuilder().create() private fun decodeAttachment(protoReader: ProtoReader): AttachmentInfo? { - val mediaInfo = protoReader.followPath(1, 1) ?: return null + val mediaInfo = protoReader.followPath(1, 1) ?: return null return AttachmentInfo( encryption = run { @@ -94,7 +99,7 @@ object MessageDecoder { fun decodeMedia(type: AttachmentType, protoReader: ProtoReader) { decodedAttachment.add( DecodedAttachment( - mediaKey = mediaReferences.getOrNull(mediaKeyIndex++), + mediaUrlKey = mediaReferences.getOrNull(mediaKeyIndex++), type = type, attachmentInfo = decodeAttachment(protoReader) ?: return ) @@ -110,7 +115,7 @@ object MessageDecoder { protoReader.followPath(1) { decodedAttachment.add( DecodedAttachment( - mediaKey = null, + mediaUrlKey = null, type = AttachmentType.STICKER, attachmentInfo = BitmojiSticker( reference = getString(2) ?: return@followPath @@ -149,7 +154,7 @@ object MessageDecoder { decodedAttachment.add( DecodedAttachment( - mediaKey = mediaReferences.getOrNull(mediaKeyIndex++), + mediaUrlKey = mediaReferences.getOrNull(mediaKeyIndex++), type = AttachmentType.NOTE, attachmentInfo = audioNote )