diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt index bdeaaf9d..11f1a06e 100644 --- a/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt +++ b/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt @@ -158,4 +158,13 @@ enum class MixerStoryType( return entries.firstOrNull { it.index == index } ?: UNKNOWN } } +} + +enum class QuotedMessageContentStatus { + UNKNOWN, + AVAILABLE, + DELETED, + JOINEDAFTERORIGINALMESSAGESENT, + UNAVAILABLE, + STORYMEDIADELETEDBYPOSTER } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt index 6c233452..04218aab 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt @@ -27,9 +27,9 @@ class EventBus( } } - inline fun subscribe(event: KClass, priority: Int? = null, crossinline listener: (T) -> Unit) = subscribe(event, { true }, priority, listener) + fun subscribe(event: KClass, priority: Int? = null, listener: (T) -> Unit) = subscribe(event, { true }, priority, listener) - inline fun subscribe(event: KClass, crossinline filter: (T) -> Boolean, priority: Int? = null, crossinline listener: (T) -> Unit): () -> Unit { + fun subscribe(event: KClass, filter: (T) -> Boolean, priority: Int? = null, listener: (T) -> Unit): () -> Unit { val obj = object : IListener { override fun handle(event: T) { if (!filter(event)) return diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/spying/MessageLogger.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/spying/MessageLogger.kt index 2bf61742..edddcd02 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/spying/MessageLogger.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/spying/MessageLogger.kt @@ -9,6 +9,7 @@ import com.google.gson.JsonObject import com.google.gson.JsonParser import me.rhunk.snapenhance.common.data.ContentType import me.rhunk.snapenhance.common.data.MessageState +import me.rhunk.snapenhance.common.data.QuotedMessageContentStatus import me.rhunk.snapenhance.common.util.ktx.longHashCode import me.rhunk.snapenhance.common.util.protobuf.ProtoReader import me.rhunk.snapenhance.core.event.events.impl.BindViewEvent @@ -38,7 +39,7 @@ class MessageLogger : Feature("MessageLogger", private val threadPool = Executors.newFixedThreadPool(10) - private val cachedIdLinks = mutableMapOf() // client id -> server id + private val cachedIdLinks = EvictingMap(500) // client id -> server id private val fetchedMessages = mutableListOf() // list of unique message ids private val deletedMessageCache = EvictingMap(200) // unique message id -> message json object @@ -112,8 +113,11 @@ class MessageLogger : Feature("MessageLogger", val uniqueMessageIdentifier = computeMessageIdentifier(conversationId, event.message.orderKey!!) val messageContentType = event.message.messageContent!!.contentType + val isMessageDeleted = messageContentType == ContentType.STATUS || event.message.messageContent!!.quotedMessage?.status?.let { + it == QuotedMessageContentStatus.DELETED || it == QuotedMessageContentStatus.STORYMEDIADELETEDBYPOSTER + } == true - if (messageContentType != ContentType.STATUS) { + if (!isMessageDeleted) { if (messageFilter.isNotEmpty() && !messageFilter.contains(messageContentType?.name)) return@subscribe if (fetchedMessages.contains(uniqueMessageIdentifier)) return@subscribe fetchedMessages.add(uniqueMessageIdentifier) @@ -136,18 +140,16 @@ class MessageLogger : Feature("MessageLogger", } } ?: return@subscribe - val messageJsonObject = deletedMessageObject.asJsonObject - //if the message is a snap make it playable - if (messageJsonObject["mMessageContent"]?.asJsonObject?.get("mContentType")?.asString == "SNAP") { - messageJsonObject["mMetadata"].asJsonObject.addProperty("mPlayableSnapState", "PLAYABLE") + if (deletedMessageObject["mMessageContent"]?.asJsonObject?.get("mContentType")?.asString == "SNAP") { + deletedMessageObject["mMetadata"].asJsonObject.addProperty("mPlayableSnapState", "PLAYABLE") } //serialize all properties of messageJsonObject and put mMessageContent & mMetadata in the message object - messageInstance.javaClass.declaredFields.forEach { field -> + messageInstance::class.java.declaredFields.forEach { field -> if (field.name != "mMessageContent" && field.name != "mMetadata") return@forEach field.isAccessible = true - messageJsonObject[field.name]?.let { fieldValue -> + deletedMessageObject[field.name]?.let { fieldValue -> field.set(messageInstance, context.gson.fromJson(fieldValue, field.type)) } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/AbstractWrapper.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/AbstractWrapper.kt index 045ff971..46f5ecc2 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/AbstractWrapper.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/AbstractWrapper.kt @@ -57,7 +57,7 @@ abstract class AbstractWrapper( protected fun field(fieldName: String, mapper: ((Any?) -> T?)? = null) = FieldAccessor(fieldName, mapper) fun > getEnumValue(fieldName: String, defaultValue: T?): T? { - if (defaultValue == null) return null + if (defaultValue == null || instance == null) return null val mContentType = XposedHelpers.getObjectField(instance, fieldName) as? Enum<*> ?: return null return java.lang.Enum.valueOf(defaultValue::class.java, mContentType.name) } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/QuotedMessage.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/QuotedMessage.kt index 68ddc916..16242e36 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/QuotedMessage.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/QuotedMessage.kt @@ -1,5 +1,6 @@ package me.rhunk.snapenhance.core.wrapper.impl +import me.rhunk.snapenhance.common.data.QuotedMessageContentStatus import me.rhunk.snapenhance.core.wrapper.AbstractWrapper import org.mozilla.javascript.annotations.JSGetter import org.mozilla.javascript.annotations.JSSetter @@ -7,4 +8,6 @@ import org.mozilla.javascript.annotations.JSSetter class QuotedMessage(obj: Any?) : AbstractWrapper(obj) { @get:JSGetter @set:JSSetter var content by field("mContent") { QuotedMessageContent(it) } + @get:JSGetter + val status by enum("mStatus", QuotedMessageContentStatus.UNKNOWN) } \ No newline at end of file