commit 3153c68516820195de07ca1bc209ef99756fc02d
parent 0e5c48062acdffc66510368922a43874f18b9e9a
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Mon,  7 Aug 2023 19:50:37 +0200

fix(message_logger): persistent after logout/clean cache

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt | 2+-
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt | 4++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/MessageLogger.kt | 51+++++++++++++++++++++++++++++++++------------------
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/AutoSave.kt | 2+-
4 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt @@ -98,7 +98,7 @@ class BridgeClient( fun getMessageLoggerMessage(conversationId: String, id: Long): ByteArray? = service.getMessageLoggerMessage(conversationId, id) - fun addMessageLoggerMessage(conversationId: String,id: Long, message: ByteArray) = service.addMessageLoggerMessage(conversationId, id, message) + fun addMessageLoggerMessage(conversationId: String, id: Long, message: ByteArray) = service.addMessageLoggerMessage(conversationId, id, message) fun deleteMessageLoggerMessage(conversationId: String, id: Long) = service.deleteMessageLoggerMessage(conversationId, id) 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 @@ -431,8 +431,8 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam //check if the messageId var contentType: ContentType = ContentType.fromId(message.contentType) - if (messageLogger.isMessageRemoved(message.clientMessageId.toLong())) { - val messageObject = messageLogger.getMessageObject(message.clientConversationId!!, message.clientMessageId.toLong()) ?: throw Exception("Message not found in database") + if (messageLogger.isMessageRemoved(message.clientConversationId!!, message.serverMessageId.toLong())) { + val messageObject = messageLogger.getMessageObject(message.clientConversationId!!, message.serverMessageId.toLong()) ?: throw Exception("Message not found in database") isArroyoMessage = false val messageContentObject = messageObject.getAsJsonObject("mMessageContent") diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/MessageLogger.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/MessageLogger.kt @@ -15,6 +15,13 @@ import java.util.concurrent.Executors import kotlin.time.ExperimentalTime import kotlin.time.measureTime +private fun Any.longHashCode(): Long { + var h = 1125899906842597L + val value = this.toString() + for (element in value) h = 31 * h + element.code.toLong() + return h +} + class MessageLogger : Feature("MessageLogger", loadParams = FeatureLoadParams.INIT_SYNC or FeatureLoadParams.ACTIVITY_CREATE_ASYNC @@ -32,23 +39,31 @@ class MessageLogger : Feature("MessageLogger", private val myUserId by lazy { context.database.getMyUserId() } - fun isMessageRemoved(messageId: Long) = deletedMessageCache.containsKey(messageId) + fun isMessageRemoved(conversationId: String, orderKey: Long) = deletedMessageCache.containsKey(computeMessageIdentifier(conversationId, orderKey)) - fun deleteMessage(conversationId: String, messageId: Long) { - fetchedMessages.remove(messageId) - deletedMessageCache.remove(messageId) - context.bridgeClient.deleteMessageLoggerMessage(conversationId, messageId) + fun deleteMessage(conversationId: String, clientMessageId: Long) { + val serverMessageId = getServerMessageIdentifier(conversationId, clientMessageId) ?: return + fetchedMessages.remove(serverMessageId) + deletedMessageCache.remove(serverMessageId) + context.bridgeClient.deleteMessageLoggerMessage(conversationId, serverMessageId) } - fun getMessageObject(conversationId: String, messageId: Long): JsonObject? { - if (deletedMessageCache.containsKey(messageId)) { - return deletedMessageCache[messageId] + fun getMessageObject(conversationId: String, orderKey: Long): JsonObject? { + val messageIdentifier = computeMessageIdentifier(conversationId, orderKey) + if (deletedMessageCache.containsKey(messageIdentifier)) { + return deletedMessageCache[messageIdentifier] } - return context.bridgeClient.getMessageLoggerMessage(conversationId, messageId)?.let { + return context.bridgeClient.getMessageLoggerMessage(conversationId, messageIdentifier)?.let { JsonParser.parseString(it.toString(Charsets.UTF_8)).asJsonObject } } + private fun computeMessageIdentifier(conversationId: String, orderKey: Long) = (orderKey.toString() + conversationId).longHashCode() + private fun getServerMessageIdentifier(conversationId: String, clientMessageId: Long): Long? { + val serverMessageId = context.database.getConversationMessageFromId(clientMessageId)?.serverMessageId?.toLong() ?: return null + return computeMessageIdentifier(conversationId, serverMessageId) + } + @OptIn(ExperimentalTime::class) override fun asyncOnActivityCreate() { if (!context.database.hasArroyo()) { @@ -70,19 +85,19 @@ class MessageLogger : Feature("MessageLogger", //exclude messages sent by me if (message.senderId.toString() == myUserId) return - val messageId = message.messageDescriptor.messageId val conversationId = message.messageDescriptor.conversationId.toString() + val serverIdentifier = computeMessageIdentifier(conversationId, message.orderKey) if (message.messageContent.contentType != ContentType.STATUS) { - if (fetchedMessages.contains(messageId)) return - fetchedMessages.add(messageId) + if (fetchedMessages.contains(serverIdentifier)) return + fetchedMessages.add(serverIdentifier) threadPool.execute { try { - context.bridgeClient.getMessageLoggerMessage(conversationId, messageId)?.let { + context.bridgeClient.getMessageLoggerMessage(conversationId, serverIdentifier)?.let { return@execute } - context.bridgeClient.addMessageLoggerMessage(conversationId, messageId, context.gson.toJson(messageInstance).toByteArray(Charsets.UTF_8)) + context.bridgeClient.addMessageLoggerMessage(conversationId, serverIdentifier, context.gson.toJson(messageInstance).toByteArray(Charsets.UTF_8)) } catch (ignored: DeadObjectException) {} } @@ -90,10 +105,10 @@ class MessageLogger : Feature("MessageLogger", } //query the deleted message - val deletedMessageObject: JsonObject = if (deletedMessageCache.containsKey(messageId)) - deletedMessageCache[messageId] + val deletedMessageObject: JsonObject = if (deletedMessageCache.containsKey(serverIdentifier)) + deletedMessageCache[serverIdentifier] else { - context.bridgeClient.getMessageLoggerMessage(conversationId, messageId)?.let { + context.bridgeClient.getMessageLoggerMessage(conversationId, serverIdentifier)?.let { JsonParser.parseString(it.toString(Charsets.UTF_8)).asJsonObject } } ?: return @@ -120,7 +135,7 @@ class MessageLogger : Feature("MessageLogger", } } - deletedMessageCache[messageId] = deletedMessageObject + deletedMessageCache[serverIdentifier] = deletedMessageObject } override fun init() { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/AutoSave.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/AutoSave.kt @@ -37,7 +37,7 @@ class AutoSave : Feature("Auto Save", loadParams = FeatureLoadParams.ACTIVITY_CR private fun saveMessage(conversationId: SnapUUID, message: Message) { val messageId = message.messageDescriptor.messageId - if (messageLogger.isMessageRemoved(messageId)) return + if (messageLogger.isMessageRemoved(conversationId.toString(), message.orderKey)) return if (message.messageState != MessageState.COMMITTED) return val callback = CallbackBuilder(callbackClass)